Codeforces Round #340 (Div. 2)E - XOR and Favorite Number(Mo's algorithm)

来源:互联网 发布:人工智能在医疗领域 编辑:程序博客网 时间:2024/05/19 01:09

题目链接:http://codeforces.com/contest/617/problem/E

题意:有一个大小为n的数组,m次询问,查询区间[l,r]中点对(i,j)满足l<=i<=j<=r且ai^ai+1^...^aj=k的数量。

思路:利用xor的性质,很容易得到sum[i-1]=sum[j]^k,所以cnt[sum[i-1]]=cnt[sum[j]^k],我们只需要纪录sum[j]^k的数量即可。不过对于左边界,要注意先进行cnt--,因为一个数xor可能等于它本身。

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <cmath>#include <queue>using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;const int maxn=1<<20;int n,m,k;int a[100010],cnt[maxn];ll ans[100010];int currentL,currentR;ll res=0;struct Node{int l;int r;int id;int block;bool operator < (const Node &a) const {return (block<a.block)||(block==a.block&&r<a.r);}}node[100010];void add(int pos){res+=cnt[a[pos]^k];cnt[a[pos]]++;}void remove(int pos){ cnt[a[pos]]--; res-=cnt[a[pos]^k];}int main(){#ifndef ONLINE_JUDGEfreopen("test.in","r",stdin);freopen("test.out","w",stdout);#endifwhile(~scanf("%d%d%d",&n,&m,&k)){for(int i=1;i<=n;i++) {scanf("%d",&a[i]);a[i]=a[i]^a[i-1];}int block_size=sqrt(n);for(int i=1;i<=m;i++){scanf("%d%d",&node[i].l,&node[i].r);node[i].id=i;node[i].block=node[i].l/block_size;}sort(node+1,node+m+1);memset(cnt,0,sizeof(cnt));currentL=1,currentR=res=0;cnt[0]=1;for(int i=1;i<=m;i++){while(currentL<node[i].l) remove(currentL-1),currentL++;while(currentL>node[i].l) currentL--,add(currentL-1);while(currentR<node[i].r) currentR++,add(currentR);while(currentR>node[i].r) remove(currentR),currentR--;ans[node[i].id]=res;}for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);}return 0;}


0 0