不开O2全RE,开了O2全WA
(不要抄啊这可是抱灵代码)
代码:
#include<bits/stdc++.h>
#define mid sum[tl-1][num[i]]-sum[hd][num[i]]
using namespace std;
int n,c,m,siz,sum[320][100005],q[100005],num[100005],ans[50][50],last_ans=0;
int pos(int x){//点在第几个块
return x%siz==0?x/siz:x/siz+1;
}
int get_first(int x){//块的第一个点
return (x-1)*siz+1;
}
int get_last(int x){//块的最后一个点
return x*siz;
}
int solve(int x,int y){
int hd=pos(x),tl=pos(y),ansa=0;
if(tl-hd<=1){
for(int i=x;i<=y;i++){
q[num[i]]++;
if(q[num[i]]%2==1&&q[num[i]]!=1) ansa--;
else if(q[num[i]]%2==0) ansa++;
}
for(int i=x;i<=y;i++) q[num[i]]--;
last_ans=ansa;
return ansa;
}
else{
ansa=ans[hd+1][tl-1];
for(int i=x;i<=get_last(hd);i++){
//if(!q[num[i]]) q[num[i]]+=(sum[tl-1][num[i]]-sum[hd][num[i]]);
q[num[i]]++;
if((q[num[i]]+mid)%2==1&&(q[num[i]]+mid)!=1) ansa--;
else if((q[num[i]]+mid)%2==0) ansa++;
}
for(int i=get_first(tl);i<=y;i++){
//if(!q[num[i]]) q[num[i]]+=(sum[tl-1][num[i]]-sum[hd][num[i]]);
q[num[i]]++;
if((q[num[i]]+mid)%2==1&&(q[num[i]]+mid)!=1) ansa--;
else if((q[num[i]]+mid)%2==0) ansa++;
}
for(int i=x;i<=get_last(hd);i++) q[num[i]]--;
for(int i=get_first(tl);i<=y;i++) q[num[i]]--;
last_ans=ansa;
return ansa;
}
}
int main(){
cin>>n>>c>>m;
siz=sqrt(n);
for(int i=1;i<=n;i++) scanf("%d",&num[i]);
for(int i=1;i<=n;i++){
sum[pos(i)][num[i]]++;
}
for(int i=1;i<=pos(n);i++){//预处理连续块内每个数出现次数
for(int j=1;j<=c;j++){
sum[i][j]+=sum[i-1][j];
}
}
for(int i=1;i<=pos(n);i++){//预处理连续块内答案
for(int j=get_first(i);j<=n;j++){
q[num[j]]++;
if(q[num[j]]%2==1&&q[num[j]]!=1) ans[i][pos(j)]--;
else if(q[num[j]]%2==0) ans[i][pos(j)]++;
}
for(int j=get_first(i);j<=n;j++){
q[num[j]]--;
}
}
for(int i=1;i<=m;i++){
int l,r;
scanf("%d%d",&l,&r);
l=(l+last_ans)%n+1,r=(r+last_ans)%n+1;
if(l>r) swap(l,r);
printf("%d\n",solve(l,r));
}
return 0;
}
and,这份代码的内存占用经常到123m,非常接近空间限制