XOR的艺术
题目描述
AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏。在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下
1、 拥有一个伤害串为长度为n的01串。
2、 给定一个范围[l,r],伤害为伤害串的这个范围内中1的个数
3、 会被随机修改伤害串中的数值,修改的方法是把[l,r]中的所有数xor上1
AKN想知道一些时刻的伤害,请你帮助他求出这个伤害
输入输出格式
输入格式:第一行两个数n,m,表示长度为n的01串,有m个时刻
第二行一个长度为n的01串,为初始伤害串
第三行开始m行,每行三个数p,l,r
若p为0,则表示当前时刻改变[l,r]的伤害串,改变规则如上
若p为1,则表示当前时刻AKN想知道[l,r]的伤害
输出格式:对于每次询问伤害,输出一个数值伤害,每次询问输出一行
输入输出样例
输入样例#1:
10 6 1011101001 0 2 4 1 1 5 0 3 7 1 1 10 0 1 4 1 2 6
输出样例#1:
3 6 1
说明
样例解释:
1011101001
1100101001
询问[1,5]输出3
1111010001
询问[1,10]输出6
0000010001
询问[2,6]输出1
数据范围:
10%数据2≤n,m≤10
另有30%数据2≤n,m≤2000
100%数据2≤n,m≤2*10^5
By:worcher
思路
线段树(带一下flag标记)
代码实现
1 #include<cstdio> 2 const int maxn=1e6; 3 const int maxl=1e6; 4 inline int min_(int x,int y){return x<y?x:y;} 5 inline int max_(int x,int y){return x>y?x:y;} 6 int n,m,l; 7 int a,b,c; 8 char ch[maxl]; 9 struct nate{int l,r,s,flag;}t[maxn]; 10 void build(int k,int l,int r){ 11 t[k].l=l,t[k].r=r; 12 if(l==r){ 13 t[k].s=ch[l-1]=='1'?1:0; 14 return; 15 } 16 int mid=l+r>>1,ls=k<<1,rs=ls+1; 17 build(ls,l,mid); 18 build(rs,mid+1,r); 19 t[k].s=t[ls].s+t[rs].s; 20 } 21 void down(int k){ 22 int ls=k<<1,rs=ls+1; 23 t[ls].s=(t[ls].r-t[ls].l+1)-t[ls].s; 24 t[rs].s=(t[rs].r-t[rs].l+1)-t[rs].s; 25 t[ls].flag^=1,t[rs].flag^=1,t[k].flag^=1;; 26 } 27 int sum(int k,int l,int r,int al,int ar){ 28 if(l==al&&r==ar) return t[k].s; 29 if(t[k].flag) down(k); 30 int ret=0,mid=l+r>>1,ls=k<<1,rs=ls+1; 31 if(al<=mid) ret+=sum(ls,l,mid,al,min_(ar,mid)); 32 if(ar>mid) ret+=sum(rs,mid+1,r,max_(al,mid+1),ar); 33 return ret; 34 } 35 void change(int k,int l,int r,int al,int ar){ 36 if(l==al&&r==ar){ 37 t[k].s=(t[k].r-t[k].l+1)-t[k].s; 38 t[k].flag^=1; 39 return; 40 } 41 if(t[k].flag) down(k); 42 int ret=0,mid=l+r>>1,ls=k<<1,rs=ls+1; 43 if(al<=mid) change(ls,l,mid,al,min_(ar,mid)); 44 if(ar>mid) change(rs,mid+1,r,max_(al,mid+1),ar); 45 t[k].s=t[ls].s+t[rs].s; 46 } 47 int main(){ 48 scanf("%d%d",&n,&m); 49 scanf("%s",ch); 50 build(1,1,n); 51 for(int i=1;i<=m;i++){ 52 scanf("%d%d%d",&a,&b,&c); 53 if(a) printf("%d\n",sum(1,1,n,b,c)); 54 else change(1,1,n,b,c); 55 } 56 return 0; 57 }