第一次写分块,挑了这题写……
然后调了一个晚上。
各种猎奇的错误都被我犯了……
人傻就是要多做题。
分块+二分
参考hzwer的
弱智错误记录:
1.数组要注意清空:这个在WC2016上已经让我的T1 60->0了……以后要认真吸取教训
2.不要乱开局部数组:这样会显著增大常数
3.要知道自己二分的是什么,不要搞着搞着就搞乱了
以上
Claris也在坚持刷题……太可怕了,本身实力超强还在刷……orzzzz
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int n,c,m,a[100005],f[1505][1505],fir[100005],las[100005],block,ans=0,L[1505],R[1505],belong[100005],tmp[100005],cnt;
struct Data{
int a,b;
friend bool operator<(Data a,Data b){
return (a.a<b.a)||(a.a==b.a && a.b<b.b);
}
}data[100005];
pair<int,int> GetLR(int L,int R){
L=(L+ans)%n+1;
R=(R+ans)%n+1;
if(L>R)swap(L,R);
return make_pair(L,R);
}
void Pre(){
for(int i=1;i<=cnt;i++){
for(int j=L[i];j<=n;j++)tmp[a[j]]=0;
int tot=0;
for(int j=L[i];j<=n;j++){
if(tmp[a[j]]%2==0 && tmp[a[j]])tot--;
tmp[a[j]]++;
if(tmp[a[j]]%2==0)tot++;
f[i][belong[j]]=tot;
}
}
//for(int i=belong[1];i<=belong[n];i++){for(int j=i;j<=belong[n];j++){printf("%d ",f[i][j]);}putchar('\n');}
for(int i=1;i<=n;i++)data[i].a=a[i],data[i].b=i;
sort(data+1,data+n+1);
for(int i=1;i<=n;i++){
if(fir[data[i].a]==0)fir[data[i].a]=i;
las[data[i].a]=i ;
}
}
int Ef_Fir(int x,int v){
int tp=214748364,l=fir[v],r=las[v];
while(l<=r){
int mid=l+r>>1;
if(x>data[mid].b)l=mid+1;
else {r=mid-1;tp=mid;}
}
return tp;
}
int Ef_Las(int x,int v){
int tp=0,l=fir[v],r=las[v];
while(l<=r){
int mid=l+r>>1;
if(x<data[mid].b)r=mid-1;
else {l=mid+1;tp=mid;}
}
return tp;
}
int Ef(int x,int y,int v){
//printf("%d %d %d | EF:%d %d\n",x,y,v,Ef_Las(y,v),Ef_Fir(x,v));
return max(Ef_Las(y,v)-Ef_Fir(x,v)+1,0);
}
int solve(int l,int r){
//printf("LR:%d %d\n",l,r);
int nwans=0,kl=belong[l],kr=belong[r];
if(kl+1==kr || kl==kr){
for(int i=l;i<=r;i++){
if(tmp[a[i]])continue;
int sp=Ef(l,r,a[i]);
if(sp%2==0){nwans++;}
//printf("%d %d %d\n",l,r,a[i]);
tmp[a[i]]=1;
}
for(int i=l;i<=r;i++)tmp[a[i]]=0;
return nwans;
}
else {
int fs=L[kl+1],la=R[kr-1];
nwans=f[kl+1][kr-1];
//printf("%d %d | NW_ANS1:%d\n",kl,kr,nwans);
for(int i=l;i<fs;i++){
if(tmp[a[i]])continue;
int sp=Ef(l,r,a[i]),sp2=Ef(fs,la,a[i]);
if(sp2%2==0 && sp%2 && sp2!=0){nwans--;}
if((sp2%2 || sp2==0) && sp%2==0){nwans++;}
//printf("SP:%d SP2:%d_%d_",sp,sp2,nwans);
tmp[a[i]]=1;
}
//printf("NW_ANS2:%d\n",nwans);
for(int i=la+1;i<=r;i++){
if(tmp[a[i]])continue;
int sp=Ef(l,r,a[i]),sp2=Ef(fs,la,a[i]);
if(sp2%2==0 && sp%2 && sp2!=0){nwans--;}
if((sp2%2 || sp2==0) && sp%2==0){nwans++;}
//printf("SP:%d SP2:%d_%d_",sp,sp2,nwans);
tmp[a[i]]=1;
}
for(int i=l;i<fs;i++)tmp[a[i]]=0;
for(int i=la+1;i<=r;i++)tmp[a[i]]=0;
return nwans;
}
}
void Read(int &x){
char ch;
while((ch=getchar())<'0' || ch>'9');
x=ch-'0';
while((ch=getchar())>='0' && ch<='9')x=x*10+ch-'0';
}
int main(){
freopen("2821.in","r",stdin);
freopen("2821.out","w",stdout);
Read(n);Read(c);Read(m);
for(int i=1;i<=n;i++){
Read(a[i]);
}
block=(int)sqrt((double)n/log(n)*log(2));
cnt=n/block+(n%block!=0);
for(int i=1;i<=n;i++)belong[i]=(i-1)/block+1;
for(int i=1;i<=cnt;i++)L[i]=R[i-1]+1,R[i]=i*block;
R[cnt]=n;
Pre();
memset(tmp,0,sizeof(tmp));
for(int i=1;i<=m;i++){
int tl,tr;
Read(tl);Read(tr);
pair<int,int> Ask=GetLR(tl,tr);
//pair<int,int> Ask=make_pair(tl,tr);
ans=solve(Ask.first,Ask.second);
printf("%d\n",ans);
}
return 0;
}