int n = read(); vector<int> a(n << 1); for (int i = 1; i < (n << 1); ++i) { a[i] = read(); } auto check = [&](int x) { vector<int> b(n << 1); for (int i = 1; i < (n << 1); ++i) { b[i] = a[i] >= x; } for (int i = 1; i < n; ++i) { if (b[n + i] == b[n + i - 1]) return b[n + i]; if (b[n - i] == b[n - i + 1]) return b[n - i]; } return b[1]; }; int l = 1, r = (n << 1) - 1; while (l <= r) { int m = (l + r) >> 1; if (!check(m)) r = m - 1; else l = m + 1; } printf("%d\n", r);
int n = read(), k = (n + 1) >> 1; vector<int> a(n), b(n); for (int i = 0; i < n; ++i) { a[i] = read(); b[i] = read(); } auto check = [&](int x) { int res = 0, pre = 0; for (int i = 0; i < n; ++i) { int r = (b[i] >= x) - (a[i] >= x); // 贡献变化量 pre = max(pre + r, r); // 史莱姆 res = max(res, pre); if (res >= k) returntrue; // 好习惯 } for (int i = 0; i < n; ++i) { res += a[i] >= x; // 初始贡献 if (res >= k) returntrue; // 好习惯++ } returnfalse; }; int l = 1, r = 1e9; while (l <= r) { int mid = (l + r) >> 1; if (check(mid)) l = mid + 1; else r = mid - 1; } printf("%d\n", r);
constexprint N = 2e5 + 8, D = 30; structTrie { int nxt[N * D][2]; int icnt[N * D]; int pcnt; intnode(){ int p = ++pcnt; nxt[p][0] = nxt[p][1] = 0; icnt[p] = 0; return p; } voidinit(){ pcnt = 0; node(); } voidmodify(int x, int d, int p = 1){ icnt[p] += d; for (int bit = D; ~bit; --bit) { bool c = x & (1ll << bit); if (!nxt[p][c]) nxt[p][c] = node(); p = nxt[p][c]; icnt[p] += d; } } ll getmax(int x, int p = 1, ll max = 0){ for (int bit = D; ~bit; --bit) { bool c = x & (1ll << bit); if (icnt[nxt[p][!c]]) p = nxt[p][!c], max |= (1ll << bit); elseif (icnt[nxt[p][c]]) p = nxt[p][c]; elsebreak; } return max; } ll getmin(int x, int p = 1, ll min = 0){ for (int bit = D; ~bit; --bit) { bool c = x & (1ll << bit); if (icnt[nxt[p][c]]) p = nxt[p][c]; elseif (icnt[nxt[p][!c]]) p = nxt[p][!c], min |= (1ll << bit); elsebreak; } return min; } } trie;
vector<vector<pair<int, int>>> E(n); for (int i = 1; i < n; i++) { int u, v, w; cin >> u >> v >> w; u--, v--; E[u].push_back({ w, v }); E[v].push_back({ w, u }); }
vector<int> dep(n), dis(n); auto dfs = [&](auto&& self, int u, int p) -> void { for (auto [w, v] : E[u]) { if (v == p) continue; dep[v] = dep[u] ^ 1; dis[v] = dis[u] ^ w; self(self, v, u); } }; dfs(dfs, 0, -1);
trie[0].init(), trie[1].init(); for (int u = 0; u < n; ++u) { trie[dep[u]].modify(dis[u], 1); }
int w = 0; while (q--) { char op; cin >> op; if (op == '^') { int y; cin >> y; w ^= y; } else { int u, x; cin >> u >> x; u--; x ^= dis[u] ^ (dep[u] * w); trie[dep[u]].modify(dis[u], -1); cout << max(trie[0].getmax(x), trie[1].getmax(x ^ w)) << " \n"[q == 0]; trie[dep[u]].modify(dis[u], 1); } }
#include<cstdio> #include<algorithm> #include<cassert> #include<cstring> constexprint N = 1e7 + 8; constexprint INF = 2147483647; using ll = longlong; usingnamespace std; inline ll read(){ ll S = 0, C = 0; char Y = getchar(); while (Y > 57 || Y < 48) C |= Y == 45, Y = getchar(); while (Y <= 57 && Y >= 48) S = (S << 3) + (S << 1) + Y - 48, Y = getchar(); return C ? -S : S; }
structTrie { structMrk { int o, a, x; // o=1:需要赋为1, a=1:需要赋为0, x=1:需要xor voidmerge(Mrk& b){ int chg; /* o=0, b.a=0 -> chg=0 -> o=0 o=0, b.a=1 -> chg=0 -> o=0 o=1, b.a=0 -> chg=0 -> o=1 o=1, b.a=1 -> chg=1 -> o=0 */ chg = o & b.a; o ^= chg;
voidmerge(int& q, int& p, int bit){ if (!q || !p) return q |= p, p = 0, void(); if (bit == -1) return p = 0, void(); push_down(q, bit); push_down(p, bit); merge(nxt[q][0], nxt[p][0], bit - 1); merge(nxt[q][1], nxt[p][1], bit - 1); p = 0; }
voidpush_down(int p, int bit){ if (mrk[p].o & (1 << bit)) merge(nxt[p][1], nxt[p][0], bit - 1); if (mrk[p].a & (1 << bit)) merge(nxt[p][0], nxt[p][1], bit - 1); if (mrk[p].x & (1 << bit)) swap(nxt[p][0], nxt[p][1]); if (nxt[p][0]) mrk[nxt[p][0]].merge(mrk[p]); if (nxt[p][1]) mrk[nxt[p][1]].merge(mrk[p]); mrk[p] = { 0, 0, 0 }; }
voidinsert(int val, int p = 0){ for (int bit = 30; ~bit; --bit) { push_down(p, bit); bool c = val & (1 << bit); if (!nxt[p][c]) { nxt[p][c] = ++pcnt; init(pcnt); } p = nxt[p][c]; } }
intquery(int val, int p = 0, ll res = 0){ for (int bit = 30; ~bit; --bit) { push_down(p, bit); bool c = val & (1 << bit); if (nxt[p][!c]) p = nxt[p][!c], res |= 1 << bit; else p = nxt[p][c]; } return res; }
voidXor(int val){ Mrk t = { 0, 0, val }; mrk[0].merge(t); } } T;
voideachT(){ int n = read(), m = read();
T.init(); while (n--) { int x = read(); T.insert(x); }
while (m--) { int op = read(), x = read(); if (op == 1) T.insert(x); if (op == 2) T.Or(x); if (op == 3) T.And(x); if (op == 4) T.Xor(x); if (op == 5) printf("%d\n", T.query(x)); } }
constexprint D = 63; structBasis { array<ll, D> h{}; bool dup = 0; // 是否有重复元素(duplication) int siz = 0;
boolinsert(ll x){ for (int bit = D - 1; ~bit; bit--) { if (x & 1ll << bit) { if (h[bit]) x ^= h[bit]; elsereturn h[bit] = x, ++siz; } } dup = 1; return0; }
boolfound(ll x){ for (int bit = D - 1; ~bit; bit--) { if (x & 1ll << bit) { if (h[bit]) x ^= h[bit]; elsereturn0; } } return1; }
// 能表示的元素个数 intsize(){ return1ll << siz; }
// 能表示的最大值 ll quemax(ll res = 0){ for (int bit = D - 1; ~bit; bit--) { res = max(res, res ^ h[bit]); } return res; }
// 能表示的最小值 ll quemin(){ if (dup) return0; for (int bit = 0; bit < D; bit++) { if (h[bit]) return h[bit]; } return0; }
ll quekth(ll k){ ll res = 0; vector<int> tmp; k -= dup; if (!k) return0; for (int i = 0; i < D; i++) { for (int bit = D; ~bit; bit--) { if (h[i] & (1ll << bit)) h[i] ^= h[bit]; } if (h[i]) tmp.push_back(h[i]); } if (k > 1ll << tmp.size()) return-1; for (int i = 0; i < tmp.size(); i++) { if (k & 1ll << i) res ^= tmp[i]; } return res; } };
constexprint D = 20; structBasis { array<int, D> h{}, t{};
Basis() { fill(t.begin(), t.end(), -1); }
voidinsert(int x, int y = 1E9){ for (int bit = D - 1; ~bit; --bit) { if (x >> bit & 1) { if (y > t[bit]) { swap(h[bit], x); swap(t[bit], y); } x ^= h[bit]; } } }
boolquery(int x, int y = 0){ for (int bit = D - 1; ~bit; --bit) { if ((x >> bit & 1) && t[bit] >= y) { x ^= h[bit]; } } return x == 0; }
// 能表示的最大值 ll quemax(ll res = 0, int y = 0){ for (int bit = D - 1; ~bit; bit--) { if (t[bit] >= y) { res = max(res, res ^ h[bit]); } } return res; } };
vector<int> val(n); for (int u = 0; u < n; u++) { cin >> val[u]; }
TREE tree(n); for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; u--, v--; tree.add(u, v); } tree.work(0);
vector<Basis> basis(n); auto dfs = [&](auto&& self, int u) -> void { basis[u].insert(val[u], tree.dep[u]); for (auto v : tree.g[u]) { basis[v] = basis[u]; self(self, v); } }; dfs(dfs, 0);
int q; cin >> q; while (q--) { int u, v, k; cin >> u >> v >> k; u--, v--; int l = tree.lca(u, v); auto bas = basis[u]; for (int i = 0; i < D; i++) { if (basis[v].t[i] >= tree.dep[l]) { bas.insert(basis[v].h[i]); } } cout << (bas.query(k, tree.dep[l]) ? "YES" : "NO") << "\n"; }
例 给定一个无限长的序列a0,a1,a2⋯,在第0 秒时,ai=i。每过一秒,序列将同时发生变化,对于i>0,ai=ai−1⊖ai⊖ai+1,特别地a0=a0∣a1。求m 秒后的an。数据范围:0⩽n,m⩽109。(CF1981B. Turtle and an Infinite Sequence)
intmain(){ // 预处理 int cnt[2] = { 0,0 }; for (int i = 0; i < 1 << 4; ++i) { int a = i >> 4 & 1; int b = i >> 3 & 1; int c = i >> 2 & 1; int d = i >> 1 & 1; int ans = ((a & b) ^ c) | d; cnt[ans] += 1; }
for (int T = read(); T--;) { int n = read(), k = read(); if (n >= (1 << k)) { printf("0\n"); continue; }
ll ans = 1; for (int bit = 0; bit < k; bit++) { ans *= cnt[(n >> bit) & 1]; } printf("%lld\n", ans); }
voideachT(){ int n = read(); int ans = 0; vector<int> dp(D); while (n--) { int x = read(); for (int k = 0; k < D; ++k) if (x & (1 << k)) ++dp[k]; int maxx = 0; for (int k = 0; k < D; ++k) maxx = max(maxx, dp[k]); for (int k = 0; k < D; ++k) if (x & (1 << k)) dp[k] = maxx; ans = max(ans, maxx); } cout << ans << endl; }
#include<algorithm> #include<cstdio> #include<vector> constint N = 6e6 + 8; constint M = 21; constint MOD = 1 << 21; inlineintread(){ int Y = getchar(), S = 0, C = 1; while (Y > 57 || Y < 48) { if (Y == 45) C = -1; Y = getchar(); } while (Y <= 57 && Y >= 48) { S = (S << 3) + (S << 1) + Y - 48; Y = getchar(); } return S * C; }
// 开21个树状数组 structBIT { int tree[N]; inlineintlowbit(int _n){ return _n & (-_n); } inlinevoidupdate(int i, int x){ for (int p = i; p < N; p += lowbit(p)) tree[p] += x; } inlineintquery(int i){ int ans = 0; for (int p = i; p >= 1; p -= lowbit(p)) ans += tree[p]; return ans; } inlineintquery(int l, int r){ returnquery(r) - query(l - 1); } } tr[M];
// 更新 将i位置的数加上num inlinevoidupdate(int i, int x){ for (int d = 0; d < M; d++) { tr[d].update((i % (1 << (d + 1))) + 1, x); } }
int p[N]; // 前缀和 intmain(){ int n = 1; // 数组中元素个数 for (int q = read(); q--;) { int t = read(), v = read(); while (t--) { update(p[n], -1); // 删除一个 n--; } n++; p[n] = (p[n - 1] + v) % MOD; // 计算新的前缀和p[n]
// 查询 分别计算每一个二进制位 按题解模拟 int ans = 0; for (int d = 0; d < M; d++) { int t = p[n] % (1 << (d + 1)); int res = tr[d].query((t + 1) + 1, (t + (1 << d)) + 1) + tr[d].query((t - (1 << (d + 1)) + 1) + 1, (t - (1 << d)) + 1); // 区间中x的个数 if (res & 1) ans += 1 << d; } ans ^= p[n]; // 再异或上p[n] printf("%d\n", ans);
update(p[n], 1); // 插入当前前缀和 } return0; }
2024 牛客多校 2E - GCD VS XOR
[[…/contests/2024牛客多校/2024-07-18:2024牛客暑期多校训练营2#E. GCD VS XOR|2024-07-18:2024牛客暑期多校训练营2]]
#include<cstdio> using ll = longlong; inline ll read(){ ll x = 0, f = 0; char c = getchar(); while (c > 57 || c < 48) f |= c == 45, c = getchar(); while (c <= 57 && c >= 48) x = (x << 3) + (x << 1) + c - 48, c = getchar(); return f ? -x : x; }
intmain(){ for (int T = read(); T--;) { ll x = read(); ll ans = x - (x & (-x)); if (ans == 0) ans = -1; printf("%lld\n", ans); } return0; }
vector<int> v[D]; for (int i = 0; i < n; ++i) { int x = read(); for (int j = 2; j <= x; ++j) read(); v[__lg(x)].push_back(x); }
int ans = 0; for (int bit = D - 1; bit >= 0; bit--) { if (v[bit].size() >= 2) { ans |= (1 << bit); ans |= (1 << bit) - 1; } elseif (v[bit].size() == 1) { if (ans & (1 << bit)) { ans |= (1 << bit) - 1; } else { ans |= (1 << bit); int x = v[bit][0] ^ (1 << bit); if (x) v[__lg(x)].push_back(x); } } }
printf("%d\n", ans); }
另有一种码量小,但复杂度高的做法,注意到∑x 很小,可以通过:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
voideachT(){ int n = read();
int ans = 0; for (int i = 0; i < n; ++i) { int x = read(), tmp = ans; for (int j = 2; j <= x; ++j) read(); for (int j = 1; j <= x; ++j) { ans = max(tmp | j, ans); } }