涉及到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 }