trie树
利用前缀和,然后注意要先插入0;
可以比较一下我的另外一篇,有一处不太一样,其他的大致相同
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define mem(i,a) memset(i,a,sizeof(i))
#define rson mid+1,r,rt<<1|1
#define lson l,mid,rt<<1
#define ll long long
#define LL long long
using namespace std;
const double eps = 0.0000001;
const int maxn = 1e5+7;
const int mod = 1e9+7;
template <typename T>inline void read(T &_x_){
_x_=0;bool f=false;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=!f;ch=getchar();}
while ('0'<=ch&&ch<='9') {_x_=_x_*10+ch-'0';ch=getchar();}
if(f) _x_=-_x_;
}
struct node{
node*ch[2];
int v;
node(){ch[0]=ch[1]=NULL;v=0;}
};
node*root=new node();
node*rt;
int id,n,k;
ll ans=0;
void update(int x){
rt=root;
for(int i=30;i>=0;i--){
id = (x>>i)&1;
if(rt->ch[id]==NULL)
rt->ch[id]=new node();
rt=rt->ch[id];
rt->v++;
}
}
void query(int m){
rt=root;
for(int level=30;level>=0;level--){
if(rt==NULL) break;
int x=(m>>level)&1;
int y=(k>>level)&1;
if(y==0){
if(rt->ch[x^1]!=NULL)
ans+=rt->ch[x^1]->v;
rt=rt->ch[x];
}else rt=rt->ch[x^1];
}
if(rt!=NULL) ans+=rt->v; //和我另一篇利用trie的博客最大的不同是这里。
}
int main(){
read(n);read(k);
update(0);
int x,sum=0;
FOR(i,1,n){
read(x);
sum^=x;
query(sum);
update(sum);
}
printf("%I64d\n",ans);
return 0;
}