817E. Choosing The Commander trie字典树
题意:现有3种操作 加入一个值,删除一个值,询问pi^x<k的个数
思路:很像以前lightoj上写过的01异或的字典树,用字典树维护数求异或值即可
/** @Date : 2017-07-02 18:58:02 * @FileName: 817E trie.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e6+20; const double eps = 1e-8; int a[N*4][3]; int sum[N*4]; int cnt = 0; void ope(int x, int f) { int bit[32]; MMF(bit); int len = 0; while(x) { bit[len++] = x % 2; x >>= 1; } int np = 0; for(int i = 31; i >= 0; i--) { if(!a[np][bit[i]]) a[np][bit[i]] = ++cnt; np = a[np][bit[i]]; sum[np] += f; } } int query(int x, int k) { int bit[32], tmp[32]; MMF(bit); MMF(tmp); int len = 0; while(x) { bit[len++] = x % 2; x >>= 1; } len = 0; while(k) { tmp[len++] = k % 2; k >>= 1; } int np = 0; int res = 0; for(int i = 31; i >= 0; i--) { if(!tmp[i] && !a[np][bit[i]]) break; if(tmp[i]==0) np = a[np][bit[i]]; else { if(a[np][bit[i]]) res += sum[a[np][bit[i]]]; if(a[np][!bit[i]] == 0) break; np = a[np][!bit[i]]; } } return res; } int main() { int q; while(cin >> q) { MMF(sum); while(q--) { int x, y; scanf("%d%d", &x, &y); if(x == 1) ope(y, 1); else if(x == 2) ope(y, -1); else if(x == 3) { int k; scanf("%d", &k); printf("%d\n", query(y, k)); } } } return 0; } //要求有异或操作 为了快速运算 使用trie字典树保存每个人对应二进制位上的数字 //并存入sum[]中 //注意空间1e5*32位以上