题目描述:
思路:
线段树维护区间1的值的个数。(用到了懒标记)。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int a[maxn],n,m;
string s;
struct stree{
int l,r;
int sum;
int add;
}t[4*maxn];
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
t[p].sum=a[l];
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
return;
}
void _new(int p,int x,int y){
if(t[p].l>=x&&t[p].r<=y){
t[p].sum=(t[p].r-t[p].l+1)-t[p].sum;
t[p].add+=1;
t[p].add%=2;
return;
}
if(t[p].add){
t[p*2].sum=(t[p*2].r-t[p*2].l+1)-t[p*2].sum;
t[p*2+1].sum=(t[p*2+1].r-t[p*2+1].l+1)-t[p*2+1].sum;
t[p*2].add+=t[p].add;
t[p*2+1].add+=t[p].add;
t[p*2].add%=2;
t[p*2+1].add%=2;
t[p].add=0;
}
int mid=(t[p].l+t[p].r)/2;
if(x<=mid) _new(p*2,x,y);
if(y>mid) _new(p*2+1,x,y);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
int ask(int p,int l,int r){
if(l<=t[p].l&&r>=t[p].r) return t[p].sum;
if(t[p].add){
t[p*2].sum=(t[p*2].r-t[p*2].l+1)-t[p*2].sum;
t[p*2+1].sum=(t[p*2+1].r-t[p*2+1].l+1)-t[p*2+1].sum;
t[p*2].add+=t[p].add;
t[p*2+1].add+=t[p].add;
t[p*2].add%=2;
t[p*2+1].add%=2;
t[p].add=0;
}
int mid=(t[p].l+t[p].r)/2,val=0;
if(l<=mid) val+=ask(p*2,l,r);
if(r>mid) val+=ask(p*2+1,l,r);
return val;
}
int main(){
scanf("%d%d",&n,&m);
cin>>s;
for(int i=1;i<=n;i++)
a[i]=s[i-1]-'0';
build(1,1,n);
for(int i=1;i<=m;i++){
int y,z,c;
char x;
cin>>x;
scanf("%d%d",&y,&z);
if(x=='0'){
_new(1,y,z);
continue;
}
if(x=='1'&&z<y) swap(z,y);
if(x=='1') cout<<ask(1,y,z)<<endl;
}
return 0;
}