已知一个长度为n的整数数列a1,a2,…,an,给定查询参数l、r,问在al,al+1,…,ar区间内,有多少子序列满足异或和等于k。也就是说,对于所有的x,y(l≤x≤y≤r),满足ax⊕ax+1⊕⋯⊕ay=k的x,y有多少组。
输入
输入第一行为3个整数n,m,k。第二行为空格分开的n个整数,即a1,a2,…,an。接下来m行,每行两个整数lj,rj,代表一次查询。
输出
输出共m行,对应每个查询的计算结果。
样例输入
4 5 1
1 2 3 1
1 4
1 3
2 3
2 4
4 4
样例输出
4
2
1
2
1
这个题是莫队算法,之前有好多题是莫队算法,然而都没看过,所以什么都不会。今天现学现用,套莫队算法模板,看着莫队算法挺简单的,后悔,没早学,不明白的看看莫队吧https://blog.csdn.net/thinfatty/article/details/72581276
https://www.bilibili.com/video/av4291097?from=search&seid=13758732447889923495
#include<stdio.h>
#include<queue>
#include<math.h>
#include<time.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(a) a&(-a)
#define PI acos(-1)
#define shortime(a) std::ios::sync_with_stdio(a);
using namespace std;
const LL mod=998244353;
//long long cmp(node a,node b){ if(a.x==b.x) return a.r>b.r;return a.x>b.x;}
LL quick(LL x,LL n,LL mod){ LL ans=1,temp=x%mod; while(n){if(n%2==1){ ans=(ans*temp)%mod;} n/=2;temp=temp*temp%mod;}return ans%mod;}
int maxn (int a,int b,int c){return max(max(a,b),max(b,c));}
LL min(LL a,LL b) {return a<b?a:b;}
int gcd (int a,int b){return b==0?a:gcd(b,a%b);}
struct node {
int l,r,id;
}Q[100005];
int n,k,m,ans[100005],flag[100005],Ans=0,b[100005];
int a[100005]={0};
int cmp (node a,node c)
{
if(b[a.l]==b[c.l]) return a.r<c.r;
return a.l<c.l;
}
int add(int x)
{
Ans+=flag[a[x]^k];
flag[a[x]]++;
}
int remove(int x)
{
Ans-=flag[a[x]^k];
flag[a[x]]--;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int nx=sqrt(n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]=a[i]^a[i-1];
b[i]=i/nx;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].id=i;
}
flag[0]=1;
sort(Q,Q+m,cmp);
int L=1,R=0;
for(int i=1;i<=m;i++)
{
while(L<Q[i].l){remove(L-1);L++;}
while(L>Q[i].l) {L--;add(L-1);}
while(R<Q[i].r) {R++;add(R);}
while(R>Q[i].r) {remove(R);R--;}
ans[Q[i].id]=Ans;
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}
补充:int add(int x)
{
Ans+=flag[a[x]^k];
flag[a[x]]++;
}
int remove(int x)
{
Ans-=flag[a[x]^k];
flag[a[x]]--;
}
这个函数可能不太容易懂,其实就是三个数异或 a^k=b; b^a=a^k^a=k;