惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Hacker News: Ask HN
Hacker News: Ask HN
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
The Last Watchdog
The Last Watchdog
TaoSecurity Blog
TaoSecurity Blog
Schneier on Security
Schneier on Security
SecWiki News
SecWiki News
V
Vulnerabilities – Threatpost
Project Zero
Project Zero
O
OpenAI News
W
WeLiveSecurity
Security Archives - TechRepublic
Security Archives - TechRepublic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
H
Hacker News: Front Page
Cisco Talos Blog
Cisco Talos Blog
Spread Privacy
Spread Privacy
Help Net Security
Help Net Security
P
Privacy & Cybersecurity Law Blog
K
Kaspersky official blog
S
Security @ Cisco Blogs
Latest news
Latest news
AWS News Blog
AWS News Blog
U
Unit 42
Martin Fowler
Martin Fowler
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Know Your Adversary
Know Your Adversary
Scott Helme
Scott Helme
博客园 - 司徒正美
B
Blog RSS Feed
C
Check Point Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Docker
Google Online Security Blog
Google Online Security Blog
Jina AI
Jina AI
aimingoo的专栏
aimingoo的专栏
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Last Week in AI
Last Week in AI
月光博客
月光博客
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
SegmentFault 最新的问题
NISL@THU
NISL@THU
T
The Blog of Author Tim Ferriss
C
Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
小众软件
小众软件

Shiroha白羽的博客

Golang 踩坑 —— interface 为参数的时候传 nil 指针 Codeforces Round 925 (Div. 3) Codeforces Round 924 (Div. 2) Codeforces Round 923 (Div. 3) Codeforces Round 922 (Div. 2) Codeforces Round 921 (Div. 2) Educational Codeforces Round 161 (Rated for Div. 2) Codeforces Round 920 (Div. 3) Codeforces Round 919 (Div. 2) Hello 2024 Good Bye 2023 Codeforces Round 918 (Div. 4) 个人备份的常用 macOS 清理命令 Codeforces Round 917 (Div. 2) Pinely Round 3 (Div. 1 + Div. 2) Educational Codeforces Round 160 (Rated for Div. 2) Codeforces Round 915 (Div. 2) Codeforces Round 914 (Div. 2) Codeforces Round 913 (Div. 3) Educational Codeforces Round 159 (Rated for Div. 2) Codeforces Round 912 (Div. 2) Codeforces Round 911 (Div. 2) CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!) Educational Codeforces Round 158 (Rated for Div. 2) Codeforces Round 910 (Div. 2) Codeforces Round 909 (Div. 3) Codeforces Round 908 (Div. 2) Educational Codeforces Round 157 (Rated for Div. 2) C++自定义的字面量 Codeforces Round 907 (Div. 2) Codeforces Round 916 (Div. 3) 关于 LRU map 的一些灵感 2023 杭州站 ICPC 现场赛 反复横跳的 Clang-Tidy(cert-dcl21-cpp) Codeforces Round 906 (Div. 2) 一段奇怪的 CPP 代码 Codeforces Round 905 (Div. 3) Codeforces Round 904 (Div. 2) Codeforces Round 903 (Div. 3) Educational Codeforces Round 156 (Rated for Div. 2) Codeforces Round 902 (Div. 2, based on COMPFEST 15 - Final Round) Codeforces Round 901 (Div. 2) Codeforces Round 899 (Div. 2) Educational Codeforces Round#155 (Div. 2) Codeforces Round 898 (Div. 4) CodeTON Round 6 (Div. 2) Codeforces Round 897 (Div. 2) Codeforces Round 896 (Div. 2) Codeforces Round 887 (Div. 2) Codeforces Round 895 (Div. 3) 左值-右值-将亡值 blog.mauve.icu Pinely Round 2 (Div. 1 + Div. 2) Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2) Codeforces Round 894 (Div. 3) Codeforces Round 888 (Div. 3) Educational Codeforces Round#153 (Div. 2) Codeforces Round 893 (Div. 2) OTPAUTH,两步验证中的通用协议 Codeforces Round 892 (Div. 2) Codeforces Round 891 (Div. 3) Codeforces Round 890 (Div. 2) Educational Codeforces Round#152 (Div. 2) blog.mauve.icu Java Script 的 null 和 undefined 随想 记一次 SQL LEFT JOIN 没有得到预期结果的错误 Codeforces Round#789(Div. 2) GCC/G++ 预编译头性能优化 使用 Junit5 和 Mockito 实现 SpringBoot 的单元测试最优美的解决方案 centOS 防火墙 docker-compse 的问题 C++ 语言实现动态变化的线程池 Codeforces Round#744 (Div. 3) 计算机图形学 Windows 通过网络访问 WSL2 原生 JavaScript 实现图片裁剪 面试复习(计算机图形学) 面试复习(算法) Codeforces Round#706(Div. 2)-Let's Go Hiking 面试复习(Java) 面试复习(Git) 面试复习(Linux) 面试复习(数据库) 面试复习(计算机网络) 面试复习(操作系统) 面试复习(C++) Codeforces Round#699 (Div. 2) 清理 WSL2 的磁盘占用 Codeforces Round#697 (Div. 3) Windows 下的 NTFS 驱动器索引 BUG 计算机网络复习 记一次 Navicat 连接 MySQL 一直报认证错误(Access denied) 计算机网络实验复习 WSL1 使用 Docker 一直无法启动 我的ACM脚印 2020牛客暑期多校训练营(第三场)D-Points Construction Problem——构造 2020牛客暑期多校训练营(第三场)E-Two Matchings——复杂思维与简单dp 2020牛客暑期多校训练营(第二场)I-Interval——最大流转对偶图求最短路 Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理 Codeforces Round 606 E. Two Fairs——图论 Codeforces Round 612 (Div. 2) C. Garland——DP
Codeforces Round 900 (Div. 3)
Shiroha · 2023-10-05 · via Shiroha白羽的博客

A. How Much Does Daytona Cost?

大致题意

给出一个数组和一个数字,问数组内是否存在某个子区间,使得给出的值出现次数最多

思路

只有一个值也是子区间,只有它出现也是出现,所以只需要判断是否存在即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, k;
cin >> n >> k;
bool flag = false;
for (int i = 0; i < n; ++i) {
int tmp;
cin >> tmp;
if (tmp == k) flag = true;
}
cout << (flag ? "YES" : "NO") << endl;
}
}

B. Aleksa and Stack

大致题意

要求你构造一个数组,长度为 $n$,严格递增,且满足 $3 \times a_{i+2} \space mod \space (a_{i+1} + a_{i+2}) \neq 0$

思路

随便递增就行,要是成立了,就把 $a_{i+2}$ 再加一不就行了。注意开头两个值不可以是 $1, 2$

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n;
cin >> n;
int a = 1, b = 3;
cout << "1 3";
for (int i = 2; i < n; ++i) {
int cur = b + 1;
while ((cur * 3) % (a + b) == 0) cur++;
cout << ' ' << cur;
a = b;
b = cur;
}
cout << endl;
}
}

C. Vasilije in Cacak

大致题意

给出一个 $n$,问能否在 $[1, n]$ 内选出 $k$ 个值,其和恰好为 $x$

思路

初始区间是 $[1, n]$,那么肯定最终能够构造出的值必定也是完全连续的,所以只需要考虑最大可能和最小可能即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
#define int long long

void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, k, x;
cin >> n >> k >> x;
int mi = (1 + k) * k / 2, ma = (n + (n - k + 1)) * k / 2;
cout << (x >= mi && x <= ma ? "YES" : "NO") << endl;
}
}

D. Reverse Madness

大致题意

这题的题意隐藏得很好,就不写大致题意了,看原文会更有味道一些

思路

首先要理清楚题目到底要我们做什么,如果直接按照题目的要求去做,反而完全不知道如何下手

在给出一个 $x$ 后,查找到一个对应的 $i$ 满足 $l_i \leq x \leq r_i$,然后翻转 $[min(x, l_i + r_i - x), max(x, l_i + r_i - x)]$ 这个区间的字符串,问最终结果

首先回来看给出的两个数组的特点,比较有意思的一条 $l_i = r_{i-1}+1$。如果把每个 $i$ 对应的区间 $[l_i, r_i]$ 单独拎出来看,会发现这些所有的区间是不会重合的,是恰好完美覆盖整个字符串的,所以,查找到一个对应的 $i$ 满足 $l_i \leq x \leq r_i$,实际上就是要找到此时的 $x$ 处于哪个区间上

再来看后面的 $[min(x, l_i + r_i - x), max(x, l_i + r_i - x)]$。因为我们已经知道 $l_i \leq x \leq r_i$,所以设 $x = l + m, r = x + n$,故可以得到 $l_i + r_i - x \rightarrow l_i + x + n - x \rightarrow l_i + n \rightarrow r_i - m - n + n \rightarrow r_i - m$,而注意到 $x = l_i + m$,所以实际上最终的区间恰好是 $[l + m, r - m]$(假定 $m$ 较小的情况下,反之也可以得到类似结果)

很显然,实际上无论怎么翻转,大家的翻转区间要么不会有交集,要么是基于同一个点进行的翻转,所以实际上只需要记录下每个点被翻转了几次即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, k;
cin >> n >> k;
string str;
str.reserve(n);
cin >> str;
vector<int> a(k), b(k);
for (auto &i: a) cin >> i;
for (auto &i: b) cin >> i;

int q;
cin >> q;
vector<bool> flag(n + 1, false);
for (int i = 0; i < q; ++i) {
int x;
cin >> x;
int index = int(upper_bound(a.begin(), a.end(), x) - a.begin()) - 1;
int l = min(a[index] + b[index] - x, x), r = max(a[index] + b[index] - x, x);
flag[l] = !flag[l];
if (r != b[index]) flag[r + 1] = !flag[r + 1];
}

for (int i = 0; i < k; ++i) {
bool f = false;
for (int l = a[i]; l <= b[i]; ++l) {
f ^= flag[l];
if (!f) cout << str[l - 1];
else cout << str[b[i] - (l - a[i]) - 1];
}
}
cout << endl;
}
}

E. Iva & Pav

大致题意

有一个数组,每次给出一个下标 $l$ 和一个目标值 $x$,问能够找到另外一个尽可能大的下标 $r$,满足 $[l, r]$ 内所有值进行 $\&$ 计算后仍然大于 $x$

思路

建了一棵线段树,然后二分答案,然后没了

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
struct SegTree {
vector<int> data;

explicit SegTree(int size) : data((size << 1) + 10) {}

static inline int get(int l, int r) { return (l + r) | (l != r); }

void up(int l, int r) {
int mid = (l + r) >> 1;
data[get(l, r)] = data[get(l, mid)] & data[get(mid + 1, r)];
}

// NOLINTNEXTLINE(*-no-recursion)
void build(int l, int r) {
if (l == r) return;
int mid = (l + r) >> 1;
build(l, mid);
build(mid + 1, r);
up(l, r);
}

// NOLINTNEXTLINE(*-no-recursion)
int query(int l, int r, int x, int y) {
if (l == x && r == y) return data[get(l, r)];
int mid = (l + r) >> 1;
if (y <= mid) return query(l, mid, x, y);
else if (x > mid) return query(mid + 1, r, x, y);
else return query(l, mid, x, mid) & query(mid + 1, r, mid + 1, y);
}
};

void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n;
cin >> n;
SegTree tree(n);
for (int i = 0; i < n; ++i) cin >> tree.data[(i + 1) << 1];
tree.build(1, n);
int q;
cin >> q;
for (int i = 0; i < q; ++i) {
int l, k;
cin >> l >> k;
if (tree.data[l << 1] < k) {
cout << -1 << ' ';
continue;
}

int ll = l, rr = n + 1;
while (ll + 1 < rr) {
int mid = (ll + rr) >> 1;
if (tree.query(1, n, l, mid) >= k) ll = mid;
else rr = mid;
}
cout << ll << ' ';
}
cout << endl;
}
}

F. Vasilije Loves Number Theory

大致题意

初始有一个值 $n$,有两种操作

  • 给出一个 $x$,使得 $n \leftarrow n \times x$,然后询问是否存在数字 $a$,满足 $gcd(a, n) = 1$ 的同时 $d(n \times a) = n$
  • 将 $n$ 改为初始值

其中 $d(x)$ 表示 $x$ 的因子数(非质因子数)

思路

首先,$n$ 几乎可以增长到非常大,所以肯定不能保存下来,当然,麻烦的事情肯定不止这个。

首先是 $d(n \times a)$ 如何计算,已知两个数的所有因子,且因子没有重复($gcd(a, n) = 1$)则此时 $d(n \times a) = d(n) \times d(a)$,而这个等式还需要 $=n$,故得到 $d(a) = \frac{n}{d(n)}$,而因为 $d(a)$ 一定是正整数,所以只需要满足右边的分数是整数即可。至于 $a$ 具体如何构造,可以直接拿一个足够大的素数的 $\frac{n}{d(n)} - 1$ 次幂即可

计算 $d(n)$ 则只需要对 $n$ 进行质因子分解即可,根据每次的乘法,进行累加质因子。而需要计算 $\frac{n}{d(n)}$ 是否是整数,则可以再对 $d(n)$ 进行质因子分解,看看两边的质因子是否有包含关系即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#define int long long

void solve() {
vector<int> prime;
vector<int> flag(1e6 + 10, true);
flag[0] = flag[1] = false;
for (int i = 2; i < flag.size(); ++i) {
if (!flag[i]) continue;
for (int j = i * i; j < flag.size(); j += i) flag[j] = false;
}
for (int i = 2; i < flag.size(); ++i) if (flag[i]) prime.push_back(i);
auto div = [&](int x, const function<void(int, int)> &callback) {
for (int i: prime) {
if (x % i != 0) continue;
int cnt = 0;
while (x % i == 0) {
cnt++;
x /= i;
}
callback(i, cnt);
if (flag[x]) {
callback(x, 1);
return;
}
}
};

int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, q;
cin >> n >> q;
map<int, int> cnt;
int dn = 1;
auto add = [&](int v, int c) {
auto iter = cnt.find(v);
if (iter == cnt.end()) {
cnt.insert({v, 0});
iter = cnt.find(v);
}
dn /= iter->second + 1;
iter->second += c;
dn *= iter->second + 1;
};
div(n, add);

for (int i = 0; i < q; ++i) {
int o;
cin >> o;
switch (o) {
case 1LL: {
int x;
cin >> x;
div(x, add);
bool f = true;
div(dn, [&](int v, int c) {
if (cnt[v] < c) f = false;
});
cout << (f ? "YES" : "NO") << endl;
break;
}
case 2LL:
cnt.clear();
dn = 1;
div(n, add);
break;
default:
break;
}
}
cout << endl;
}
}

G. wxhtzdy ORO Tree

大致题意

有一棵树,树上每个点上都有值,每次询问给出两个点 $u, v$,需要寻找一个 $z$,使得

  • $z$ 在 $u, v$ 的树上路径上,即最短路径上
  • $g(u, z) + g(z, v)$ 的值尽可能大

其中 $g(x, y)$ 表示在树上的 $x, y$ 两点的最短路径上的所有值进行或运算,得到的结果的值在二进制上,有多少个 bit 位是 1

思路

首先要找树上路径,大概率会用到 lca 算法。接下来因为要求算树上路径的或和,所以还可以在 lca 上加一个父节点的或运算的倍增表

而要寻找的点一定在两者的倍增节点上,由于目标节点一定是恰好可以产生一个比特位从 $o \rightarrow 1$ 的变化的,所以可以再记录下一个点的所有比特位,在其的最近的哪个父亲那完成了 $o \rightarrow 1$ 的变化

然后遍历所有的可能计算即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; ++i) cin >> a[i];
struct node {
int v, n;
};
vector<node> edge(n * 2);
vector<int> head(n + 1, -1);
for (int i = 0; i < n - 1; ++i) {
int u, v;
cin >> u >> v;
edge[i << 1] = {v, head[u]};
edge[(i << 1) | 1] = {u, head[v]};
head[u] = i << 1;
head[v] = (i << 1) | 1;
}

// dep is the depth of node
vector<int> dep(n + 1);
// fa for lca, orFa for calculate 'or sum' faster, miB for the deepest node `x` which (x & (1 << i)) is true
vector<vector<int>> fa(n + 1), orFa(n + 1), miB(n + 1);

for (auto &i: fa) i.resize(20);
for (auto &i: orFa) i.resize(20);
for (auto &i: miB) i.resize(30);

// build lca
function<void(int, int)> dfs = [&](int u, int p) {
dep[u] = dep[p] + 1;

fa[u][0] = p;
orFa[u][0] = a[p];
for (int i = 1; i < 20; ++i) {
fa[u][i] = fa[fa[u][i - 1]][i - 1];
orFa[u][i] = orFa[u][i - 1] | orFa[fa[u][i - 1]][i - 1];
}
for (int i = 0; i < 30; ++i) miB[u][i] = (a[p] & (1 << i)) ? p : miB[p][i];
for (int i = head[u]; ~i; i = edge[i].n) if (edge[i].v != p) dfs(edge[i].v, u);
};
// lca
function<int(int, int)> lca = [&](int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
int diff = dep[u] - dep[v];
for (int i = 0; i < 20; ++i) if (diff & (1 << i)) u = fa[u][i];
if (u == v) return u;
for (int i = 19; i >= 0; --i) {
if (fa[u][i] == fa[v][i]) continue;
u = fa[u][i];
v = fa[v][i];
}
return fa[u][0];
};
// calculate the 'or sum' from u to v
function<int(int, int)> ors = [&](int u, int v) {
int p = lca(u, v);
// -1 to avoid 'or' the parent double times
int ld = dep[u] - dep[p] - 1, rd = dep[v] - dep[p] - 1;
int ls = 0, rs = 0, ru = u, rv = v;

if (ld > 0)
for (int i = 0; i < 20; ++i)
if (ld & (1 << i)) {
ls |= orFa[ru][i];
ru = fa[ru][i];
}
if (rd > 0)
for (int i = 0; i < 20; ++i)
if (rd & (1 << i)) {
rs |= orFa[rv][i];
rv = fa[rv][i];
}
return ls | rs | a[p] | (p == u ? 0 : a[u]) | (p == v ? 0 : a[v]);
};
// calculate the bit count
function<int(int)> bitCount = [&](int u) {
int res = 0;
while (u) {
res += u & 1;
u >>= 1;
}
return res;
};
// find on the path (u -> p)
function<int(int, int, int)> cal = [&](int u, int v, int p) {
int ans = bitCount(a[u]) + bitCount(ors(u, v));
for (int i = 0; i < 30; ++i) {
if (miB[u][i] == 0 || miB[u][i] == u) continue;
if (dep[p] > dep[miB[u][i]]) continue;
ans = max(ans, bitCount(ors(u, miB[u][i])) + bitCount(ors(v, miB[u][i])));
}
return ans;
};
dfs(1, 0);

int q;
cin >> q;
for (int i = 0; i < q; ++i) {
int u, v;
cin >> u >> v;
int p = lca(u, v);
cout << max(cal(u, v, p), cal(v, u, p)) << ' ';
}
cout << endl;
}
}