代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[200007];
struct SegmentTree{
int l,r;
int sum1,sum2;
int flag;
}t[800007];
void print(int id){
if(t[id].l==t[id].r){cout<<t[id].sum2<<" ";return;}
print(id<<1);print(id<<1|1);
return;
}
void pushup(int id){
t[id].sum1=t[id<<1].sum1+t[id<<1|1].sum1;
t[id].sum2=t[id<<1].sum2+t[id<<1|1].sum2;
return;
}
void build(int id,int l,int r){
t[id].l=l;t[id].r=r;
if(l==r){
if(a[l]==0)t[id].sum1=1;
else t[id].sum2=1;
return;
}
int mid=(l+r)>>1;
build(id<<1,l,mid);build(id<<1|1,mid+1,r);
pushup(id);
return;
}
void pushdown(int id){
if(t[id].flag){
if(t[id].flag%2==1){
swap(t[id<<1].sum1,t[id<<1].sum2);
swap(t[id<<1|1].sum1,t[id<<1|1].sum2);
t[id<<1].flag+=t[id].flag;
t[id<<1|1].flag+=t[id].flag;
t[id].flag=0;
}
else return;
}
return;
}
void update(int id,int l,int r){
if(l<=t[id].l&&t[id].r<=r){
swap(t[id].sum1,t[id].sum2);
++t[id].flag;
return;
}
pushdown(id);
int mid=(t[id].l+t[id].r)>>1;
if(l<=mid)update(id<<1,l,r);
if(r>mid)update(id<<1|1,l,r);
pushup(id);
return;
}
int query(int id,int l,int r){
if(l<=t[id].l&&t[id].r<=r)return t[id].sum2;
pushdown(id);
int mid=(t[id].l+t[id].r)>>1;
if(r<=mid)return query(id<<1,l,r);
else if(l>mid)return query(id<<1|1,l,r);
else return query(id<<1,l,r)+query(id<<1|1,l,r);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;++i){
char x;cin>>x;
a[i]=(int)x-48;
}
build(1,1,n);
for(int i=1;i<=m;++i){
char op;int l,r;
cin>>op>>l>>r;
if(op=='0')update(1,l,r);
else cout<<query(1,l,r)<<'\n';
}
return 0;
}
学校教的是c++,关于scanf和printf并没有提及太多。看一本通和博客自己了解的,然后发现写不对原谅我太菜了(JSOIOJ不支持关闭同步,会RE)