5301. [CQOI2018] XOR Sequence [Mo Team]

Description

Given an integer sequence a[1],a[2],…,a[n] of length n, given query parameters l, r, ask how many consecutive subs are in the interval [l,r]
The sequence satisfies the XOR sum equal to k .
That is to say, for all x, y (l≤x≤y≤r), how many groups of x and y can satisfy a[x]^a[x+1]^...^a[y]=k.

Input

The first line of the input file is 3 integers n, m, k.
The second line is n integers separated by spaces, namely ai, a2, . . . an.
The next m lines, each with two integers lj, rj, represent a query.
1≤n,m≤105,O≤k,ai≤105,1≤lj≤rj≤n

Output

The output file has m lines in total, corresponding to the calculation results of each query.

Sample Input

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

Sample Output

4
2
1
2
1
 
I can't go on like this anymore.
Yesterday, I played the board for a day, and I feel like my brain is rusted. QAQ... The
question has been killed for a long time... Obviously the sub-sequences should be discontinuous.
At first glance, this form of the question basically didn't run,
but if the two ends join /Subtract a number, the effect of this number on the interval is close to its continuous segment,
which is obviously unmaintainable. So an XOR prefix and sum can be maintained
because a[x] xor a[x+1]...xor a[y-1] xor a[y] is equivalent to sum[y] xor sum[x-1]
then We can use Mo team to maintain the prefix sum.
Every time you add/delete the prefix sum to the Mo team, you only need to consider how many numbers are XOR equal to k with the current number, and you can open a bucket.
Because we need sum[x-1]~sum[y] when querying the interval [x,y], the left endpoint needs to be decremented by one when reading in.

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define N (500000+100)
 7 using namespace std;
 8 
 9 struct node{int x,y,num,id,ans;}ask[N];
10 int Keg[N],sum[N],n,m,k,x,now;
11 
12 bool cmp1(node a,node b){return a.id==b.id?a.y<b.y:a.id<b.id;}
13 bool cmp2(node a,node b){return a.num<b.num;}
14 
15 void Ins(int pos){now+=Keg[sum[pos]^k];    Keg[sum[pos]]++;}
16 void Del(int pos){Keg[sum[pos]]--; now-=Keg[sum[pos]^k];}
17 
18 int main()
19 {
20     scanf("%d%d%d",&n,&m,&k);
21     int unit=sqrt(n);
22     for (int i=1; i<=n; ++i)
23         scanf("%d",&x),sum[i]=sum[i-1]^x;
24     for (int i=1; i<=m; ++i)
25     {
26         scanf("%d%d",&ask[i].x,&ask[i].y);
27         ask[i].x--; ask[i].num=i;
28          ask[i].id=ask[i].x/unit;
29     }
30     sort(ask+1,ask+m+1,cmp1);
31     
32     int l=1,r=0;
33     for (int i=1; i<=m; ++i)
34     {
35         while (l<ask[i].x) Del(l++);
36         while (l>ask[i].x) Ins(--l);
37         while (r<ask[i].y) Ins(++r);
38         while (r>ask[i].y) Del(r--);
39         ask[i].ans=now;
40     }
41     
42     sort(ask+1,ask+m+1,cmp2);
43     for (int i=1; i<=m; ++i)
44         printf("%d\n",ask[i].ans);
45 }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324768673&siteId=291194637