Блог пользователя qzqzgfy

Автор qzqzgfy, история, 10 лет назад, По-английски
E. XOR and Favorite Number
                                       617E
                            time limit per test4 seconds
                        memory limit per test256 megabytes
                                inputstandard input
                                outputstandard output

Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pair li and ri and asks you to count the number of pairs of integers i and j, such that l ≤ i ≤ j ≤ r and the xor of the numbers ai, ai + 1, ..., aj is equal to k.

Input The first line of the input contains integers n, m and k (1 ≤ n, m ≤ 100 000, 0 ≤ k ≤ 1 000 000) — the length of the array, the number of queries and Bob's favorite number respectively.

The second line contains n integers ai (0 ≤ ai ≤ 1 000 000) — Bob's array.

Then m lines follow. The i-th line contains integers li and ri (1 ≤ li ≤ ri ≤ n) — the parameters of the i-th query.

Output Print m lines, answer the queries in the order they appear in the input.

Sample test(s) input 6 2 3 1 2 1 1 0 3 1 6 3 5 output 7 0 input 5 3 1 1 1 1 1 1 1 5 2 4 1 3 output 9 4 4

。。好题,我一开始觉得一定是按分块分的可持久化字典树,具体做法呢就是先利用莫队算法,然后将区间内的所有a[i]都加入字典树,然后对于每个节点我们都有对应能异或得k的所有对应节点,然后我们边修改l和r边修改ans。 然后因为位数在20左右,所以非常完美,不会爆炸。

以上都是yy,其实这题只要用一个sum【i】数组存一个前缀异或和,sum[r]^sum[l-1]就是a[l]到a[r]的异或和了,这样我们每加入一个sum[i]都有对应的op[sum[i]],这样我们再记录一个cnt[i]代表目前a[j]值为i的j的个数 这样ans就能+=cnt[i]*cnt[op[i]],此外,如果k=0,那么便有l=r的情况出现,然而k=0我们只需要特殊处理即可,此题还需要注意longlong,反正我把全部int改成long long了。 代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#define ll long long
struct wow{
	ll id,ans,l,r;
}ans[1000005];
ll l,r,mx,a[1000005],block,n,m,k,now,cnt[2000005],sum[1000005],op[2000005],pos[1000005];
bool cmp1(wow q,wow w){
	if (pos[q.l]==pos[w.l]) return q.r<w.r;
	return pos[q.l]<pos[w.l];
}
bool cmp2(wow q,wow w){
	return q.id<w.id;
}
void updata(ll x,ll v){
	if (k!=0)
	now-=cnt[sum[x]]*cnt[op[sum[x]]];
	else
	now-=((cnt[sum[x]]-1)*(cnt[sum[x]]))/2;
	cnt[sum[x]]+=v;
	if (k!=0)
	now+=cnt[sum[x]]*cnt[op[sum[x]]];
	else
	now+=((cnt[sum[x]]-1)*(cnt[sum[x]]))/2;
}
int main(){
	//freopen("tx.in","r",stdin);
	scanf("%I64d%I64d%I64d",&n,&m,&k);
	block=sqrt(n);
	for (int i=1;i<=n;i++)
	 pos[i]=i/block;
	for (int i=1;i<=n;i++)
	 scanf("%I64d",&a[i]);
	for (int i=1;i<=n;i++) 
	 sum[i]=sum[i-1]^a[i],mx=std::max(mx,sum[i]);
	for (int i=0;i<=mx;i++)
	 op[i]=i^k;
	for (int i=1;i<=m;i++){
		scanf("%I64d%I64d",&ans[i].l,&ans[i].r);
		ans[i].l--;
		ans[i].id=i;
		ans[i].ans=0;
	}  
	std::sort(ans+1,ans+1+m,cmp1);
    l=ans[1].l;r=ans[1].l;cnt[sum[l]]++;now=0;
    for (int i=1;i<=m;i++){
    	if (l<ans[i].l){
    		for (int j=l;j<ans[i].l;j++)
    		 updata(j,-1);
    	}
    	else
    	if (l>ans[i].l){
    		for (int j=l-1;j>=ans[i].l;j--)
    		 updata(j,1);
    	}
    	l=ans[i].l;
    	if (r<ans[i].r){
    		for (int j=r+1;j<=ans[i].r;j++)
    		 updata(j,1);
    	}
    	else
    	if (r>ans[i].r){
    		for (int j=r;j>ans[i].r;j--)
    		 updata(j,-1);
    	}
    	r=ans[i].r;
		ans[i].ans=now;    
    }
    std::sort(ans+1,ans+1+m,cmp2);
    for (int i=1;i<=m;i++)
     printf("%I64d\n",ans[i].ans);
} 
  • Проголосовать: нравится
  • -26
  • Проголосовать: не нравится

»
10 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by qzqzgfy (previous revision, new revision, compare).

»
10 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by qzqzgfy (previous revision, new revision, compare).

»
10 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Too TM water le:)