您的位置:首页 > 其它

BZOJ_5301_[Cqoi2018]异或序列&&CF617E_莫队

2018-04-20 16:53 447 查看

Description

已知一个长度为 n 的整数数列 a[1],a[2],…,a
,给定查询参数 l、r ,问在 [l,r] 区间内,有多少连续子 序列满足异或和等于 k 。 也就是说,对于所有的 x,y (l≤x≤y≤r),能够满足a[x]^a[x+1]^…^a[y]=k的x,y有多少组。

Input

输入文件第一行,为3个整数n,m,k。 第二行为空格分开的n个整数,即ai,a2,….an。 接下来m行,每行两个整数lj,rj,表示一次查询。 1≤n,m≤105,O≤k,ai≤105,1≤lj≤rj≤n

Output

输出文件共m行,对应每个查询的计算结果。

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 分析: 把异或求前缀异或,然后莫队,维护一个桶,加上一个$x$ 答案就加上桶里$x\;xor\;k$的值,减去一个数同理。   代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define N 100050
typedef long long ll;
ll ans
,now;
int n,a
,m,k,h[2000050],pos
,s
,size,block,L
,R
;
struct A {
int id,l,r;
}q
;
bool cmp(const A &x,const A &y) {
if(pos[x.l]==pos[y.l]) return x.r<y.r;
return pos[x.l]<pos[y.l];
}
void del(int x) {
h[x]--;
now-=h[x^k];
}
void add(int x) {
now+=h[x^k];
h[x]++;
}
void solve() {
int l=0,r=-1,i;
for(i=1;i<=m;i++) {
while(l<q[i].l) del(s[l]),l++;
while(r>q[i].r) del(s[r]),r--;
while(l>q[i].l) l--,add(s[l]);
while(r<q[i].r) r++,add(s[r]);
ans[q[i].id]=now;
}
}
int main() {
scanf("%d%d%d",&n,&m,&k);
int i,j;
size=sqrt(n); block=n/size;
pos[0]=1;
for(i=1;i<=block;i++) {
L[i]=R[i-1]+1; R[i]=size*i;
for(j=L[i];j<=R[i];j++) {
pos[j]=i;
}
}
if(R[block]!=n) {
block++; for(i=R[block-1];i<=n;i++) pos[i]=block;
}
for(i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=s[i-1]^a[i];
for(i=1;i<=m;i++) {
scanf("%d%d",&q[i].l,&q[i].r); q[i].l--;
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
solve();
for(i=1;i<=m;i++) printf("%lld\n",ans[i]);
}
/*
50 2 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
17 35
3 35
*/

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: