题目描述
Bob has a favorite number kk and a_{i}ai of length nn . Now he asks you to answer mm queries. Each query is given by a pair l_{i}li and r_{i}ri and asks you to count the number of pairs of integers ii and jj , such that l<=i<=j<=rl<=i<=j<=r and the xor of the numbers a_{i},a_{i+1},...,a_{j}ai,ai+1,...,aj is equal to kk .
输入格式
The first line of the input contains integers n , m and k ( 1<=n,m<=1000001<=n,m<=100000 , 0<=k<=1000000 ) — the length of the array, the number of queries and Bob's favorite number respectively.
The second line contains nn integers a_{i}ai ( 0<=ai<=1000000 ) — Bob's array.
Then mm lines follow. The ii -th line contains integers l_{i}li and r_{i}ri ( 1<=l_{i}<=r_{i}<=n1<=li<=ri<=n ) — the parameters of the ii -th query.
输出格式
Print mm lines, answer the queries in the order they appear in the input.
题意翻译
- 给定一个长度为 nn 的序列 aa,然后再给一个数字 kk,再给出 mm 组询问,每组询问给出一个区间,求这个区间里面有多少个子区间的异或值为 kk。
- 1 \le n,m \le 10 ^ 51≤n,m≤105,0 \le k,a_i \le 10^60≤k,ai≤106,1 \le l_i \le r_i \le n1≤li≤ri≤n。
Translated by @char32_t,Reformed by @明依。
输入输出样例
输入 #1复制
6 2 3
1 2 1 1 0 3
1 6
3 5
输出 #1复制
7
0
输入 #2复制
5 3 1
1 1 1 1 1
1 5
2 4
1 3
输出 #2复制
9
4
4
说明/提示
In the first sample the suitable pairs of ii and jj 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.
思路:
首先,a[i]^a[i+1]^...^a[j] = (a[1]^a[2]^...^a[i-1]) ^ (a[1]^a[2]^..^a[j]),即:区间[i,j]的异或值等于区间[1,i-1]的异或值异或区间[1,j]的异或值。(^: xor)因为a^a=0,0^x=x,所以:
[1,i-1]的异或值 ^ [1,j]的异或值 = [1,i-1]的异或值 ^ [1,i-1]的异或值 ^ [i,j]异或值 = 0 ^ [i,j]异或值 = [i,j]的异或值.
这样先求出前缀的异或值,然后问题就转化[l,r]有多少对(i,j)使前缀异或值a[i] xor a[j] = k。(每一对(i,j)就代表一个子区间)
又因为:a xor b = k <==> a xor k = b ,所以找区间中b = a xor k这个的值出现的个数即为异或对的值为k的个数,
这样用莫队算法,即可用cnt[i]数组维护前缀异或值为i的个数,并统计答案即可。
莫队算法参考的视频:https://www.bilibili.com/video/BV1zE411673h?from=search&seid=13310194198957878438
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define int long long
using namespace std;
const int maxn=1e5+5;
struct Q
{
int l,r,id;
}q[maxn];
int a[maxn],n,m,k;
int pos[maxn],cnt[1<<20],res,ans[maxn];
void add(int x)
{
res+=cnt[a[x]^k];
cnt[a[x]]++;
}
void del(int x)
{
cnt[a[x]]--;
res-=cnt[a[x]^k];
}
signed main()
{
cin>>n>>m>>k;
int siz=sqrt(n);
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]^=a[i-1];
pos[i]=i/siz;
}
for(int i=0;i<m;i++){
cin>>q[i].l>>q[i].r;
q[i].l--;
q[i].id=i;
}
sort(q,q+m,[](Q x,Q y){
return pos[x.l]==pos[y.l]?x.r<y.r:pos[x.l]<pos[y.l];
});
int l=1,r=0;
//cnt[0]=1;
for(int i=0;i<m;i++){
while(q[i].l<l) add(--l);
while(q[i].r>r) add(++r);
while(q[i].l>l) del(l++);
while(q[i].r<r) del(r--);
ans[q[i].id]=res;
}
for(int i=0;i<m;i++) cout<<ans[i]<<endl;
return 0;
}