天天看點

異或序列

題目:

https://www.luogu.com.cn/problem/P4462

利用的異或的字首和性質,

有多少個區間[l,r]滿足異或起來為k

異或滿足字首和

有多少個sumr^sum(l-1) =k

sum(l-1) =k^sumr

要将l換成l-1

#include<bits/stdc++.h>     #include<stdio.h>     using namespace std;     const int maxn=1e5+7;     int n,m,k,block,belong[maxn],sum[maxn],arr[maxn],has[maxn],ans[maxn];     inline int gcd(int a, int b)     { int r; while (b > 0) { r = a % b; a = b; b = r; }return a; }     struct Q     {         int l,r,id;         bool operator <(const Q &b)         {             if(belong[l]!=belong[b.l])                 return l<b.l;             else                 return r<b.r;         }     }query[maxn];     int L,R;     int ret=0;     int fa=0;     int s=0;     inline void add(int x)     {       ret+=has[x^k];       ++has[x];     }     inline void del(int x)     {   --has[x];       ret-=has[x^k];     }     //´Ó[L,R]×ªÒÆµ½[l,r]     /*     void GetNew(int l,int r,int L,int R)     {         while(R<r) add(arr[++R]);         while(L>l) add(arr[--L]);         while(R>r) del(arr[R--]);         while(L<l) del(arr[L++]);     }     */     int main()     {         scanf("%d%d%d",&n,&m,&k);          block=sqrt(n);       for(int i=1;i<=n;++i)       {  scanf("%d",&arr[i]);     arr[i]^=arr[i-1];            belong[i]=(i-1)/block+1;       }      int ans[maxn];       for(int i=1;i<=m;++i)       {         int l,r;         scanf("%d%d",&l,&r);         query[i]={l-1,r,i};       }       sort(query+1,query+m+1);      L=1;       for(int i=1;i<=m;++i)       {  int l=query[i].l;          int r=query[i].r;          int id=query[i].id;           //auto[l,r,id]=query[i];           while(R<r) add(arr[++R]);           while(L>l) add(arr[--L]);           while(R>r) del(arr[R--]);           while(L<l) del(arr[L++]);           //printf("ret=%d\n",ret);           ans[id]=ret;       }       for(int i=1;i<=m;++i)       {   printf("%d\n",ans[i]);       }     }      

繼續閱讀