涉及到lazy思想的线段树,难度大一些,不过幸好只有一种操作,扛得下。
1 #include <stdio.h> 2 #include <string.h> 3 #define N 100005 4 int tree[4*N],D; 5 bool rev[4*N]; 6 void build(int cur,int x,int y) 7 { 8 int mid=(x+y)>>1,lc=cur<<1,rc=lc|1; 9 rev[cur] = 0; 10 tree[cur] = 0; 11 if(x == y) 12 return ; 13 build(lc,x,mid); 14 build(rc,mid+1,y); 15 } 16 void update(int n) 17 { 18 tree[n] = tree[n<<1] + tree[n<<1|1]; 19 } 20 void pushdown(int cur,int x,int y) 21 { 22 int mid=(x+y)>>1,lc=cur<<1,rc=lc|1; 23 if(rev[cur]) 24 { 25 rev[lc] ^= 1; rev[rc] ^= 1; 26 tree[lc] = mid-x+1 - tree[lc]; 27 tree[rc] = y-mid - tree[rc]; 28 rev[cur] = 0; 29 } 30 } 31 void change(int cur,int x,int y,int s,int t) 32 { 33 int mid=(x+y)>>1,lc=cur<<1,rc=lc|1; 34 if(s <= x && y <= t) 35 { 36 rev[cur] ^= 1; 37 tree[cur] = y-x+1 -tree[cur]; 38 return ; 39 } 40 pushdown(cur,x,y); 41 if(s <= mid) change(lc,x,mid,s,t); 42 if(t >= mid+1) change(rc,mid+1,y,s,t); 43 update(cur); 44 } 45 void query(int cur,int x,int y,int s,int t,int &ans) 46 { 47 int mid=(x+y)>>1,lc=cur<<1,rc=lc|1; 48 if(s <= x && y <= t) 49 { 50 ans += tree[cur]; 51 return ; 52 } 53 pushdown(cur,x,y); 54 if(s <= mid) 55 query(lc,x,mid,s,t,ans); 56 if(t >= mid+1) 57 query(rc,mid+1,y,s,t,ans); 58 } 59 int main() 60 { 61 int m,n,k,x,y,ans; 62 while(~scanf("%d%d",&n,&m)) 63 { 64 for(D = 1; D < n; D <<= 1); 65 build(1,0,D-1); 66 while(m--) 67 { 68 scanf("%d%d%d",&k,&x,&y); 69 if(k) 70 { 71 ans = 0; 72 query(1,0,D-1,x,y,ans); 73 printf("%d\n",ans); 74 } 75 else change(1,0,D-1,x,y); 76 } 77 } 78 return 0; 79 }