Codeforces 671E 莫隊入門
阿新 • • 發佈:2019-01-03
看了卿學姐的演算法講堂寫的。
使用莫隊的複雜度大約n*sqrt(n)
離線,根據l和r所在的塊排序。
在知道(L,R)的情況下要在O(1)時間內得出(L±1,R±1),所以這樣就可以向左右兩邊擴充套件區間了。
具體就是add和del函式不一樣
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1<<20;
LL a[maxn],flag[maxn];
LL ans[maxn];
int pos[maxn];
struct node{
int l,r,id;
}Q[maxn];
int n,m,k;
LL Ans=0;
int L=1,R=0;
bool cmp(node a,node b){
if(pos[a.l]==pos[b.l])
return pos[a.r]<pos[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-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(L<Q[i].l){
del(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){
del(R);
R--;
}
ans[Q[i].id]=Ans;
}
for(int i=1;i<=m;i++){
printf("%lld ",ans[i]);
}
return 0;
}