Codeforces 617E XOR and Favorite Number[莫队算法]

题意:给你n个数,再给定m个询问和一个数k,每个询问是一个区间 [ l ,r ]

问这个区间中有多少个i j 满足a[i]^a[i+1]^...^a[j]==k;

刚开始得知是莫队算法,去了解了下这个算法然后开始写,发现还是不知道怎么处理

最后是照着别人代码写的,还看了好久,,最后还是理解了  自己还是弱啊。。(不过对异或和这个算法也更了解了)


#include<bits/stdc++.h>
using namespace std;
#define N 1000005
struct lx{
	int l,r,id;
}p[N];
int a[N],num[N*2],b[N];
long long ans[N];
int n,m,k,sq;

bool cmp(lx a,lx b){
	if(a.l/sq!=b.l/sq)return a.l/sq<b.l/sq;
	else return a.r<b.r;
}
void work(){
	memset(num,0,sizeof(num));
	int left=1,right=0;
	long long cnt=0;
	for(int i=0;i<m;++i){
		while(right<p[i].r){         //	 
			right++;                 //  b[i]为前缀和,求a[l]^a[l+1]^...^a[r]==k即求b[l-1]^b[r]==k即b[r]^k==b[l-1];(由a^a=0可以得到)
			cnt+=num[b[right]^k];    //  num[]数组表示right之前有几个i是满足b[right]^k==b[i-1]的;
			num[b[right]]++;         //  这样cnt直接加上num[b[right]^k]就是当前left->right的答案;
		}                            //	 再更新num[b[right]];
		while(right>p[i].r){
			num[b[right]]--;
			cnt-=num[b[right]^k];
			right--;
		}
		while(left>p[i].l-1){
			left--;
			cnt+=num[b[left]^k];
			num[b[left]]++;
		}
		while(left<p[i].l-1){
			num[b[left]]--;
			cnt-=num[b[left]^k];
			left++;
		}
		ans[p[i].id]=cnt;
	}
}
int main(){
	memset(b,0,sizeof(b));
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		b[i]=b[i-1]^a[i];
	}
	sq=(int)sqrt(n);
	for(int i=0;i<m;++i){
		scanf("%d%d",&p[i].l,&p[i].r);
		p[i].id=i;
	}
	sort(p,p+m,cmp);
	work();
	for(int i=0;i<m;++i){
		printf("%I64d\n",ans[i]);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值