数学模型:
维持一个01序列,支持2种操作:
1、将给定区间内的数取反;
2、查询给定区间内1的个数。
这题就是“暑假集训每日一题0712”的简化版
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <stdio.h> #define N 100001 int n,m,ans; int sum[4*N],rev[4*N]; void update(int cur) { int ls=cur<<1,rs=cur<<1|1; sum[cur]=sum[ls]+sum[rs]; } void pushdown(int cur,int x,int y) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; if(rev[cur]) { sum[ls]=mid-x+1-sum[ls]; sum[rs]=y-mid-sum[rs]; rev[ls]^=1; rev[rs]^=1; rev[cur]=0; } } void build(int cur,int x,int y) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; sum[cur]=rev[cur]=0; if(x==y) return; build(ls,x,mid); build(rs,mid+1,y); } void reverse(int cur,int x,int y,int s,int t) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; if(x>=s && y<=t) { rev[cur]^=1; sum[cur]=y-x+1-sum[cur]; return; } pushdown(cur,x,y); if(mid>=s) reverse(ls,x,mid,s,t); if(mid+1<=t) reverse(rs,mid+1,y,s,t); update(cur); } void query(int cur,int x,int y,int s,int t) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; if(x>=s && y<=t) { ans+=sum[cur]; return; } pushdown(cur,x,y); if(mid>=s) query(ls,x,mid,s,t); if(mid+1<=t) query(rs,mid+1,y,s,t); } int main() { int i,opt,x,y; while(~scanf("%d%d",&n,&m)) { build(1,1,n); for(i=0;i<m;i++) { scanf("%d%d%d",&opt,&x,&y); if(opt) { ans=0; query(1,1,n,x,y); printf("%d\n",ans); } else reverse(1,1,n,x,y); } } return 0; }