题解:
把数字转化成2进制之后,用字典树去维护。
想到字典树之后就应该是一道很容易写的题目了。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e6 + 100; int n, k; int a[N]; int s[30], ss[30]; int tree[1<<24][2]; int cnt[1<<24]; int tot = 2; void add(){ int rt = 1; for(int i = 0; i < 30; ++i){ int id = s[i]; if(!tree[rt][id]) tree[rt][id] = ++tot; ++cnt[tree[rt][id]]; rt = tree[rt][id]; } } void add(int x){ for(int i = 29; i >= 0; --i){ s[i] = + (x & 1); x >>= 1; } add(); } LL ans = 0; void Find(){ int rt = 1; for(int i = 0; i < 30; ++i){ if(!rt) return ; if(s[i] == 0 && ss[i] == 0){ // cout << " *** " << endl; ans += cnt[tree[rt][1]]; rt = tree[rt][0]; } else if(s[i] == 0 && ss[i] == 1){ rt = tree[rt][1]; } else if(s[i] == 1 && ss[i] == 0){ // cout << "??" << endl; ans += cnt[tree[rt][0]]; rt = tree[rt][1]; } else if(s[i] == 1 && ss[i] == 1){ rt = tree[rt][0]; } // cout << i << " " << ss[i] << " " <<ans << endl; } ans += cnt[rt]; } int main(){ scanf("%d%d", &n, &k); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); for(int i = 29; i >= 0; --i){ ss[i] = + (k & 1); k >>= 1; } add(0); for(int i = 1; i <= n; ++i){ a[i] ^= a[i-1]; add(a[i]); Find(); } cout << ans << endl; return 0; }View Code