Codeforces - 617E 年轻人的第一道莫队

我对莫队算法最为纠结的地方就是区间端点处,应该是像代码里那样理解吧
cnt[i]表示i出现的次数
maxn开2e6比较保险

/*H E A D*/
struct Query{
	int l,r,id;
}q[maxn];
int size;
bool cmp(Query a,Query b){
	if(a.l/size!=b.l/size) return a.l/size<b.l/size;
	else return a.r<b.r;
} 
ll cnt[maxn],a[maxn];
ll ans[maxn];
int main(){
	int n,m,k;
	while(cin>>n>>m>>k){
		memset(cnt,0,sizeof cnt);
		rep(i,1,n) a[i]=read();
		rep(i,2,n) a[i]^=a[i-1];
		rep(i,1,m){
			q[i].l=read();
			q[i].r=read();
			q[i].id=i;
		}
		size=sqrt(n);
		sort(q+1,q+1+m,cmp);
		int l=1,r=0;//l-1=0 r=0
		cnt[0]++;
		ll tmp=0;
		rep(i,1,m){
			while(l<q[i].l){//删去[l,q[i].l-1] 
				cnt[a[l-1]]--;
				tmp-=cnt[a[l-1]^k];
				l++;
			}
			while(l>q[i].l){//添加[q[i].l,l-1] 
				tmp+=cnt[a[l-2]^k];//l-1-1
				cnt[a[l-2]]++;
				l--;
			}
			while(r<q[i].r){//增加[r+1,q[i].r] 
				tmp+=cnt[a[r+1]^k];
				cnt[a[r+1]]++;
				r++;
			}
			while(r>q[i].r){//删去[q[i].r+1,r] 
				cnt[a[r]]--;
				tmp-=cnt[a[r]^k];
				r--;
			}
			ans[q[i].id]=tmp;
		}
		rep(i,1,m) println(ans[i]);
	}
	return 0;
}
posted @ 2018-02-07 22:06  Caturra  阅读(175)  评论(0)    收藏  举报