bzoj1858: [Scoi2010]序列操作

很早之前就做了

线段树裸题

据说可以只维护一段区间是否全是1或者0,复杂度应该没有保证?也不觉得更好写一些。。

 

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<string>
  7 
  8 using namespace std;
  9 
 10 void setIO(const string& a) {
 11     freopen((a+".in").c_str(), "r", stdin);
 12     freopen((a+".out").c_str(), "w", stdout);
 13 }
 14 
 15 struct Data {
 16     int s[2], l[2], r[2], m[2];
 17     Data() {
 18         memset(s, 4*(sizeof s), 0);
 19     }
 20 };
 21 
 22 int n;
 23 
 24 Data merge(const Data& lhs, const Data& rhs) {
 25     Data res;
 26     
 27     int n1 = lhs.s[0] + lhs.s[1];
 28     int n2 = rhs.s[0] + rhs.s[1];
 29     
 30     for(int i = 0; i < 2; i++) {
 31         res.s[i] = lhs.s[i] + rhs.s[i];
 32         res.l[i] = lhs.l[i];
 33         if(lhs.l[i] == n1) res.l[i] += rhs.l[i];
 34         res.r[i] = rhs.r[i];
 35         if(rhs.r[i] == n2) res.r[i] += lhs.r[i];
 36         res.m[i] = max(max(lhs.m[i], rhs.m[i]), lhs.r[i] + rhs.l[i]);
 37     }
 38     
 39     return res;
 40 }
 41 
 42 const int N = 100000 + 10;
 43 
 44 int a[N];
 45 
 46 
 47 struct SegmentTree {
 48     Data da[N * 4];    
 49     int tag[N * 4];// -1 : none  2 : rever
 50     int lft, rgt, w;
 51     
 52     void add_tag(int s, int l, int r, int w) {
 53         if(w == -1) return;
 54         int len = r - l + 1;
 55         if(w != 2) {
 56             tag[s] = w;
 57             da[s].s[w] = da[s].m[w] = da[s].l[w] = da[s].r[w] = len;
 58             w ^= 1;
 59             da[s].s[w] = da[s].m[w] = da[s].l[w] = da[s].r[w] = 0;
 60         }else {
 61             swap(da[s].s[0], da[s].s[1]);
 62             swap(da[s].l[0], da[s].l[1]);
 63             swap(da[s].r[0], da[s].r[1]);
 64             swap(da[s].m[0], da[s].m[1]);
 65             if(tag[s] == -1) tag[s] = w;
 66             else if(tag[s] == 2) tag[s] = -1;
 67             else tag[s] ^= 1;
 68         }
 69     }
 70     
 71     #define mid ((l + r) >> 1)
 72     #define ls s << 1, l, mid
 73     #define rs s << 1 | 1, mid + 1, r
 74     
 75     void down(int s, int l, int r) {
 76         if(tag[s] == -1) return;
 77         add_tag(ls, tag[s]);
 78         add_tag(rs, tag[s]);
 79         tag[s] = -1;
 80     }
 81     
 82     void build(int s, int l, int r) {
 83         tag[s] = -1;
 84         if(l == r) {
 85             scanf("%d", &w);
 86             da[s].s[w] = da[s].l[w] = da[s].r[w] = da[s].m[w] = 1;
 87             w ^= 1;
 88             da[s].s[w] = da[s].l[w] = da[s].r[w] = da[s].m[w] = 0;
 89             return;
 90         }
 91         build(ls);
 92         build(rs);
 93         da[s] = merge(da[s << 1], da[s << 1 | 1]);
 94     }
 95     
 96     Data query(int s, int l, int r) {
 97         if(lft <= l && r <= rgt) return da[s];
 98         down(s, l, r);
 99         if(rgt <= mid) return query(ls);
100         if(mid < lft) return query(rs);
101         return merge(query(ls), query(rs));
102     }
103     
104     void modify(int s, int l, int r) {
105         if(lft <= l && r <= rgt) {
106             add_tag(s, l, r, w);
107             return;
108         }
109         down(s, l, r);
110         if(lft <= mid) modify(ls);
111         if(mid < rgt) modify(rs);
112         da[s] = merge(da[s << 1], da[s << 1 | 1]);
113     }
114     
115     #undef mid
116     #undef ls
117     #undef rs
118     
119     Data Query(int l, int r) {
120         lft = l, rgt = r;
121         return query(1, 1, n);
122     }
123     
124     void Modify(int l, int r, int w) {
125         lft = l, rgt = r, this->w = w;
126         modify(1, 1, n);
127     }
128     
129 }seg;
130 
131 int main() {
132     int m, opt, l, r;
133     scanf("%d%d", &n, &m);
134     seg.build(1, 1, n);
135 //    cerr << seg.Query(1, 6).s[1] << endl;
136     while(m--) {
137         scanf("%d%d%d", &opt, &l, &r); ++l, ++r;
138         if(opt <= 2) seg.Modify(l, r, opt);
139         else if(opt == 3) printf("%d\n", seg.Query(l, r).s[1]);
140         else printf("%d\n", seg.Query(l, r).m[1]);
141     }
142     
143     return 0;
144 }

 

posted @ 2015-11-30 11:04  Showson  阅读(185)  评论(0编辑  收藏  举报