CodeForces - 617E - E. XOR and Favorite Number(莫队)

E. XOR and Favorite Number

time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard 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 nm 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.

Examples

input

Copy

6 2 3
1 2 1 1 0 3
1 6
3 5

output

Copy

7
0

input

Copy

5 3 1
1 1 1 1 1
1 5
2 4
1 3

output

Copy

9
4
4

Note

In the first sample the suitable pairs of i and j for the first query are: (1, 2), (1, 4), (1, 5), (2, 3), (3, 6), (5, 6), (6, 6). Not a single of these pairs is suitable for the second query.

In the second sample xor equals 1 for all subarrays of an odd length.

题意:给你n(<=1e5)个数,m(<=1e5)次查询,再给你一个数k(<=1e6),每次查询一个区间[l,r],问此区间内有多少个子区间的异或值为k。

思路:

对于任意一个区间,我们都可以把[l,r]的异或值化成[1,r]^[1,l-1]的值。

即 任意两个前缀异或区间(l!=r)即可唯一的确定一个原区间,且异或值可以直接算出来。

(莫队上的)l范围为0~n-1,r为1~n。(0时即所选闭区间左端点为1)

对于任意一个前缀异或值a[i],我们记录num[a[i]]为a[i]出现的次数。

因为我们求的是a[l-1]^a[r]=k

两边同时异或k得 k^a[l-1]^a[r]=0

即k^a[l-1]=a[r]

也就是说 我们每次修改i,只需要考虑k^a[i]对答案的影响以及对num[a[i]]的影响即可。

当我们加入i这个点时,先num[a[i]]++,再sum+=num[k^a[i]]。

当我们删除i这个点时,先sum-=num[k^a[i]],再num[a[i]]--。

注意上面l和r的范围不同,对应的while需要稍作修改。

代码:

#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn=500010;
ll n,m,k,sz;
ll a[maxn];
ll sum,tmp[maxn],qian[maxn*10];
ll id[maxn];
ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
void add(int i,ll v)
{
    if(v>0)
    {
        sum+=qian[a[i]^k];
        qian[a[i]]+=v;
    }
    else
    {
        qian[a[i]]+=v;
        sum-=qian[a[i]^k];
    }

}
struct ac
{
    ll x,y;
}ans[maxn];
struct node
{
    int l,r,id;
}q[maxn];
bool cmp(node a,node aa)
{
    return id[a.l]==id[aa.l]?a.r<aa.r:a.l<aa.l;
}
int main()
{
    int T,cas=1;
    while(scanf("%lld%lld%lld",&n,&m,&k)!=EOF)
    {
        sz=sqrt(n);
        memset(tmp,0,sizeof(tmp));
        memset(qian,0,sizeof(qian));
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            id[i]=(i-1)/sz+1;
            if(i>1) a[i]^=a[i-1];
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].l--;
            q[i].id=i;
        }
        sort(q,q+m,cmp);
        qian[0]=1;
        int l=0,r=0;sum=0;
        for(int i=0;i<m;i++)
        {
            while(l<q[i].l){add(l,-1);l++;}
            while(l>q[i].l){add(l-1,1);l--;}
            while(r<q[i].r){add(r+1,1);r++;}
            while(r>q[i].r){add(r,-1);r--;}

            ans[q[i].id].x=sum;
        }
        for(int i=0;i<m;i++)
        {
            printf("%lld\n",ans[i].x);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/88353426
今日推荐