下面这段代码(P3870 [TJOI2009] 开关)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int N1=sqrt(N);//
//const int N1=320;
int n,m,a[N];
int len;
int L[N1],R[N1];
int pos[N],open[N1],tag[N1];
void change(int l,int r){
int p=pos[l],q=pos[r];
if(p==q){
int cnt1=0,cnt2=0;
for(int i=l;i<=r;i++){
if(a[i]==0)a[i]=1,cnt1++;
else a[i]=0,cnt2++;
}
if(tag[p]==0)open[p]+=cnt1-cnt2;
else open[p]+=cnt2-cnt1;
return;
}
//处理整块
for(int i=p+1;i<=q-1;i++){
open[i]=R[i]-L[i]+1-open[i];
tag[i]^=1;
}
//处理零散块
int cnt1=0,cnt2=0;
for(int i=l;i<=R[p];i++){
if(a[i]==0)a[i]=1,cnt1++;
else a[i]=0,cnt2++;
}
if(tag[p]==0)open[p]+=cnt1-cnt2;
else open[p]+=cnt2-cnt1;
cnt1=0,cnt2=0;
for(int i=L[q];i<=r;i++){
if(a[i]==0)a[i]=1,cnt1++;
else a[i]=0,cnt2++;
}
if(tag[q]==0)open[q]+=cnt1-cnt2;
else open[q]+=cnt2-cnt1;
}
int query(int l,int r){
int p=pos[l],q=pos[r];
if(p==q){
int ans=0;
for(int i=l;i<=r;i++)if(a[i]==1)ans++;
if(tag[p])return r-l+1-ans;
else return ans;
}
int ans=0;
for(int i=p+1;i<=q-1;i++)ans+=open[i];
int cnt1=0,cnt2=0;
for(int i=l;i<=R[p];i++)if(a[i]==1)cnt1++;
for(int i=L[q];i<=r;i++)if(a[i]==1)cnt2++;
if(tag[p])ans+=R[p]-l+1-cnt1;else ans+=cnt1;
if(tag[q])ans+=r-L[q]+1-cnt2;else ans+=cnt2;
return ans;
}
int main(){
//printf("%d\n",N1);
scanf("%d%d",&n,&m);
//for(int i=1;i<=n;i++)a[i]=1;
len=sqrt(n);
for(int i=1;i<=len;i++){
L[i]=(i-1)*len+1;
R[i]=i*len;
}
if(R[len]!=n){
len++;
L[len]=R[len-1]+1;
R[len]=n;
}
for(int i=1;i<=len;i++){
for(int j=L[i];j<=R[i];j++){
pos[j]=i;
//open[i]=R[i]-L[i]+1;
}
}
while(m--){
int c,l,r;
scanf("%d%d%d",&c,&l,&r);
//printf("pos %d %d\n",pos[l],pos[r]);
if(c==0)change(l,r);
else printf("%d\n",query(l,r));
}
return 0;
}
开了O2tle成50tps,不开O2是100tps,而如果把第七行改为第八行,开O2就能过了,为什么?