題目描述
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
思路:
線段樹,只需要把Lazy標記部分改一下。
代碼:
1 #include<cstdio> 2 using namespace std; 3 const int N=200005; 4 5 int n,m,Sum[N<<2],Lazy[N<<2]; 6 //char str[N]; 7 8 void read(int &now) 9 { 10 now=0;char c=getchar(); 11 while(c<'0'||c>'9')c=getchar(); 12 while(c>='0'&&c<='9')now=now*10+c-'0',c=getchar(); 13 } 14 15 void PushUp(int rt) 16 { 17 Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1]; 18 } 19 void PushDown(int rt,int m) 20 { 21 if(Lazy[rt]) 22 { 23 Lazy[rt<<1]^=1; 24 Lazy[rt<<1|1]^=1; 25 Sum[rt<<1]=(m-(m>>1))-Sum[rt<<1];//異或(取反),將原先狀態全部翻轉 26 Sum[rt<<1|1]=(m>>1)-Sum[rt<<1|1];//該區間一共(r-l+1)>>1 個元素,減去自己即為異或后狀態 27 Lazy[rt]=0; 28 } 29 } 30 void Build(int l,int r,int rt) 31 { 32 Lazy[rt]=0; 33 if(l==r) 34 { 35 int a; 36 scanf("%1d",&a); 37 Sum[rt]= a?1:0; 38 //Sum[rt]= str[l]=='1'?1:0; 39 return; 40 } 41 int m=(l+r)>>1; 42 Build(l,m,rt<<1); 43 Build(m+1,r,rt<<1|1); 44 PushUp(rt); 45 } 46 void ModifyXor(int l,int r,int rt,int L,int R) 47 { 48 if(L<=l && r<=R) 49 { 50 Lazy[rt]^=1; 51 Sum[rt]=r-l+1-Sum[rt]; 52 return; 53 } 54 PushDown(rt,r-l+1); 55 int m=(l+r)>>1; 56 if(L<=m) ModifyXor(l,m,rt<<1,L,R); 57 if(m<R) ModifyXor(m+1,r,rt<<1|1,L,R); 58 PushUp(rt); 59 } 60 int QuerySum(int l,int r,int rt,int L,int R) 61 { 62 if(L<=l && r<=R) return Sum[rt]; 63 PushDown(rt,r-l+1); 64 int m=(l+r)>>1,res=0; 65 if(L<=m) res+=QuerySum(l,m,rt<<1,L,R); 66 if(m<R) res+=QuerySum(m+1,r,rt<<1|1,L,R); 67 return res; 68 } 69 70 int main() 71 { 72 read(n);read(m);//scanf("%s",str+1); 73 Build(1,n,1); 74 for(int i=1;i<=m;i++) 75 { 76 int p,l,r; 77 read(p);read(l);read(r); 78 if(p) 79 printf("%d\n",QuerySum(1,n,1,l,r)); 80 else 81 ModifyXor(1,n,1,l,r); 82 } 83 return 0; 84 }