Consecutive Sum
又来水一发blog...
本来是昨天补codechef的题,最后一道题是可持久化字典树,然后去黄学长博客看了看
觉得字典树写法有点不太一样,就想着用黄学长的板子写码几道题吧...
最后发现...其实是可持久化字典树跟普通字典树写法不一样...我好傻逼...
区间异或和
可以先把前缀异或和插入到字典树中,然后去贪心
求最大值就是要求从高到低尽量不一样
高位不一样优先
用一个bit数组来存放好看多了
偷偷摸摸顺便学了快读板子...虽说可能没啥用...
#include <bits/stdc++.h> using namespace std; const int maxn = 2e6 + 10; int sum[50000 + 10]; int ans1, ans2; int bit[35]; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } struct Trie { int tol; int Next[maxn][2]; void init() { tol = 0; memset(Next, 0, sizeof(Next)); } void insert(int x) { int root = 0; for (int i = 30; i >= 0; i--) { int id = x & bit[i]; id >>= i; if (!Next[root][id]) Next[root][id] = ++tol; root = Next[root][id]; } } void query(int x) { int temp1 = 0, root1 = 0, root2 = 0, temp2 = 0; for (int i = 30; i >= 0; i--) { int id = x & bit[i]; id >>= i; if (Next[root1][id ^ 1]) root1 = Next[root1][id ^ 1], temp1 += bit[i]; else root1 = Next[root1][id]; if (Next[root2][id]) root2 = Next[root2][id]; else root2 = Next[root2][id ^ 1], temp2 += bit[i]; } ans1 = max(ans1, temp1); ans2 = min(ans2, temp2); } } trie; int main() { bit[0] = 1; for(int i = 1; i <= 30; i++) bit[i] = bit[i-1] << 1; int T; T = read(); // cin >> T; int kase = 0; while (T--) { int n = read(); // Trie trie; trie.init(); ans1 = 0; ans2 = 0x3f3f3f3f; trie.insert(0); for (int i = 1; i <= n; i++) { int x; cin >> x; sum[i] = sum[i-1] ^ x; trie.query(sum[i]); trie.insert(sum[i]); } printf("Case %d: %d %d", ++kase, ans1, ans2); puts(""); } return 0; }