题目在这里
这个oi博客终于开始写题解啦,可喜可贺。
其实这道题非常容易,只要维护一个01区间,支持查询区间和以及区间翻转即可。当然是使用线段树咯。
区间翻转其实就是用区间总的数字个数减去当前区间和,成为新的区间和。用标记记录一下就好。
自己写的时候脑子不清楚,每一次change操作都把lazy[o]设为1,其实应该是lazy[o]^=1,否则就永远都是反转这个区间,就不对了。应该让它在第二次操作的时候再反转回来。
感觉好久没有写题了,所以AC还是很开心的。
代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using namespace std;
const int maxn = 500005;
long long sumv[maxn],lazy[maxn];
int n,m;
void pushdown(int o,int l,int r)
{
     if(lazy[o]==1)
     {
        int mid=(l+r)>>1;
        lazy[o]=0;
        lazy[lson]^=1;lazy[rson]^=1;
        sumv[lson]= (mid-l+1)-sumv[lson];
        sumv[rson]=(r-mid)-sumv[rson];
     }
}
void pushup(int o)
{
    //cout<<"up: "<<o<<" "<<sumv[o]<<endl;
    sumv[o]=sumv[lson]+sumv[rson];
    //cout<<sumv[o]<<endl;
}
void change(int o,int l,int r,int ql,int qr)
{
     //pushup(o);
     int mid = (l+r)>>1;
     if(ql <= l && r <= qr)
     {
           lazy[o]^=1;
           int len=r-l+1;
           sumv[o]=len-sumv[o];
           return;
     }
     pushdown(o,l,r);
     if (qr <= mid) change(lson,l,mid,ql,qr);
     else if (ql > mid) change(rson,mid+1,r,ql,qr);
     else
     {
         change(lson,l,mid,ql,mid);
         change(rson,mid+1,r,mid+1,qr);
     }
     pushup(o);
}
int query(int o,int l,int r,int ql,int qr)
{
     //pushdown(o,l,r);
    // pushup(o);
     int mid = (l+r)>>1;
     if(ql <= l && r <= qr) return sumv[o];
     pushdown(o,l,r);
     if (qr <= mid) return query(lson,l,mid,ql,qr);
     else if (mid < ql) return query(rson,mid+1,r,ql,qr);
     else
     {
          return query(lson,l,mid,ql,mid) + query(rson,mid+1,r,mid+1,qr);
     }
}
int main()
{
    scanf("%d%d",&n,&m);
    //build(1,1,n);
    memset(sumv,0,sizeof sumv);
    memset(lazy,0,sizeof lazy);
    while(m--)
    {
       int op;
       scanf("%d",&op);
       if(op == 0)
       {
             int a,b;
             scanf("%d%d",&a,&b);
             change(1,1,n,a,b);
             //cout<<lazy[1]<<lazy[2]<<endl;
       }
       else if(op == 1)
       {
            int a,b;
            scanf("%d%d",&a,&b);
            int ans=0;
            ans = query(1,1,n,a,b);
            printf("%d\n",ans);
       }
    }
    return 0;
}
ps:抱歉今天并没有按照昨天说的去学习KMP,明天争取可以。