voidsolve(){ 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; } }
voidsolve(){ 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; } }
再来看后面的 $[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$ 较小的情况下,反之也可以得到类似结果)
voidsolve(){ 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]; structnode { 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; } }