仅#2、#11 AC;手造数据和题解对拍均未发现问题,如果能给我一组数据卡掉我也行 /kl
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int n,k;
int len;
int lp[1004],rp[1004];//块的左右端点[l,r]
bool flg[200004];//亮灯情况,打lazytag则未修改
int sum[1004];//块亮灯和,与lazytag无关
bool lzt[1004];//lazytag,表示某块的flg未取反(sum已计算)
void pushdown(int p){
if(lzt[p]){
for(int i=lp[p];i<=rp[p];i++)
flg[i]=!flg[i];
lzt[p]=false;
}
}
void add(int l,int r){
int p=(l-1)/len,q=(r-1)/len;
if(p==q){//在同一块
for(int i=l;i<=r;i++){
if(flg[i]){
flg[i]=false;
sum[p]--;
}
else{
flg[i]=true;
sum[p]++;
}
}
return;
}
pushdown(p);
for(int i=l;i<=rp[p];i++){//左边pushdown后暴力更新
if(flg[i]){
flg[i]=false;
sum[p]--;
}
else{
flg[i]=true;
sum[p]++;
}
}
for(int j=p+1;j<=q-1;j++){//整块,这里lazytag直接取非;由于j不会取到最后一块,故一定是长len的块,所以sum直接变成len-sum
sum[j]=len-sum[j];
lzt[j]=!lzt[j];
}
pushdown(q);
for(int i=lp[q];i<=r;i++){//右边
if(flg[i]){
flg[i]=false;
sum[q]--;
}
else{
flg[i]=true;
sum[q]++;
}
}
}
int ask(int l,int r){
int p=(l-1)/len,q=(r-1)/len;
int ans=0;
if(p==q){//在同一块
pushdown(p);
for(int i=l;i<=r;i++){
if(flg[i])
ans++;
}
return ans;
}
pushdown(p);
for(int i=l;i<=rp[p];i++){//左边pushdown后暴力查询
if(flg[i])
ans++;
}
for(int j=p+1;j<=q-1;j++){//sum与lazytag无关,直接累加
ans+=sum[j];
}
pushdown(q);
for(int i=lp[q];i<=r;i++){//右边
if(flg[i])
ans++;
}
return ans;
}
int main(){
int m,c,a,b;
scanf("%d%d",&n,&m);
len=sqrt(n);
k=(n-1)/len;
for(int j=0;j<k;j++){
lp[j]=j*len+1;
rp[j]=(j+1)*len;
}
lp[k]=k*len+1;
rp[k]=n;
//printf("len:%d\n",len);
while(m--){
scanf("%d%d%d",&c,&a,&b);
if(c==0){
add(a,b);
}
else{
printf("%d\n",ask(a,b));
}
/*printf("= ");
for(int i=1;i<=n;i++)
printf("%d ",flg[i]?1:0);
printf("\n= ");
for(int j=0;j<=k;j++){
printf("%d-%d",sum[j],lzt[j]?1:0);
for(int i=0;i<len*2-3;i++)
printf(" ");
}
puts("");*/
}
return 0;
}
/*by Shen_Linwood*/
谢谢~