【题目链接】
早上刚在CC上做了,中午就被人搬到BZOJ了。。
不知道为什么n开50wRE,开了52w卡了下内存就过了。
【CC上这题题解】
/* Pigonometry */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 520005, maxk = 21, maxnode = maxn * maxk; int root[maxn], triecnt, son[maxnode][2], sum[maxnode], bin[maxk]; inline int iread() { int f = 1, x = 0; char ch = getchar(); for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1; for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; return f * x; } inline void insert(int &pos, int c) { int now = ++triecnt, last = pos; pos = now; for(int i = maxk - 1; i >= 0; i--) { son[now][0] = son[last][0]; son[now][1] = son[last][1]; sum[now] = sum[last] + 1; bool ind = c & bin[i]; last = son[last][ind]; now = son[now][ind] = ++triecnt; } son[now][0] = son[last][0]; son[now][1] = son[last][1]; sum[now] = sum[last] + 1; } inline int query(int last, int now, int c) { int ans = 0; for(int i = maxk - 1; i >= 0; i--) { bool ind = c & bin[i]; if(sum[son[now][ind ^ 1]] - sum[son[last][ind ^ 1]] > 0) now = son[now][ind ^ 1], last = son[last][ind ^ 1], ans |= (ind ? 0 : bin[i]); else now = son[now][ind], last = son[last][ind], ans |= (ind ? bin[i] : 0); } return ans; } inline int findless(int last, int now, int c) { int ans = 0; for(int i = maxk - 1; i >= 0; i--) { bool ind = c & bin[i]; if(ind) ans += sum[son[now][0]] - sum[son[last][0]]; if(sum[son[now][ind]] - sum[son[last][ind]] == 0) return ans; now = son[now][ind]; last = son[last][ind]; } ans += sum[now] - sum[last]; return ans; } inline int findkth(int last, int now, int k) { int ans = 0; for(int i = maxk - 1; i >= 0; i--) { int tmp = sum[son[now][0]] - sum[son[last][0]]; if(tmp >= k) now = son[now][0], last = son[last][0]; else k -= tmp, now = son[now][1], last = son[last][1], ans |= bin[i]; } return ans; } int main() { bin[0] = 1; for(int i = 1; i < maxk; i++) bin[i] = bin[i - 1] << 1; int n = 0; for(int T = iread(); T; T--) { int opt = iread(); opt--; if(opt == 0) { int x = iread(); n++; insert(root[n] = root[n - 1], x); } else if(opt == 1) { int l = iread(), r = iread(), x = iread(); printf("%d\n", query(root[l - 1], root[r], x)); } else if(opt == 2) { int k = iread(); n -= k; triecnt = root[n + 1] - 1; } else if(opt == 3) { int l = iread(), r = iread(), x = iread(); printf("%d\n", findless(root[l - 1], root[r], x)); } else if(opt == 4) { int l = iread(), r = iread(), k = iread(); printf("%d\n", findkth(root[l - 1], root[r], k)); } } return 0; }