E. Beautiful Subarrays

来源:互联网 发布:淘宝融合期 编辑:程序博客网 时间:2024/06/07 08:02

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 longusing 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;}