CodeForces - 617E XOR and Favorite Number 莫队算法

https://vjudge.net/problem/CodeForces-617E

题意,给你n个数ax,m个询问Ly,Ry,  问LR内有几对i,j,使得ai^...^ aj =k.

题解:第一道莫队题。

技巧:前缀亦或。flag数组:利用XOR的性质。

   莫队的区间排序及处理。

   id的处理:因为排序打乱了询问顺序,所以用id记录原来的顺序。

 四个月后的补充: 关于XOR的性质: x^k=y <=> x^y=k. 所以每次读入一个a[i],Ans +=flag[a[i]^k]. It would be better if we call flag a 'cnt' array!

坑点:打错了一个字母,结果tle了好久

 

//#define _CRT_SECURE_NO_WARNINGS

#include<bits/stdc++.h>
using namespace std;
const int maxn = 120010;
struct node {
int l, r, id;

}Q[maxn];
long long ans[maxn];
long long flag[5000000];
int a[maxn],pos[maxn];
int n, m, k;
int L = 1, R=0;
long long Ans=0;
bool cmp(node a, node b) {
if (pos[a.l] == pos[b.l]) 
return a.r < b.r;
return pos[a.l] < pos[b.l];

}
void add(int x) {
Ans += flag[a[x] ^ k];
flag[a[x]]++;
}
void del(int x) {
flag[a[x]]--;
Ans -= flag[a[x] ^ k];
}

int main() {
scanf("%d%d%d", &n, &m, &k);
int sz = sqrt(n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
a[i] = a[i] ^ a[i - 1];
pos[i] = i / sz;
}
for (int i = 1; i <= m; i++) {
scanf("%d%d", &Q[i].l, &Q[i].r);
Q[i].id = i;
}
sort(Q + 1, Q + 1 + m,cmp);
flag[0] = 1;
for (int i = 1; i <= m; i++) {
while (R < Q[i].r) {
R++;
add(R);
}
while (L > Q[i].l) {
L--;
add(L - 1);
}
while (R > Q[i].r) {    
del(R);
R--;

}
while (L < Q[i].l) {
del(L - 1);
L++;
}
ans[Q[i].id] = Ans;
//
}
for (int i = 1; i <= m; i++)
cout << ans[i] << endl;

}

 

posted @ 2018-03-09 13:40  SuuTTT  阅读(172)  评论(0编辑  收藏  举报