HDU3397 Sequence operation

  原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=3397

  线段树,区间合并。

  节点记录的信息如下:

  int l, r, c;                      // 区间左端点,右端点,长度
  int lsum1, rsum1, msum1;            // 左连续1长度,右连续1长度,区间最长连续1长度
  int lsum0, rsum0, msum0;            // 左连续0长度,右连续0长度,区间最长连续0长度
  int sum;                           // 区间1的个数


  题目许多更新询问操作都是比较熟悉的了。

  这道题对于01反转操作我是这样做的:从上面列出来的节点信息可以看到,既记录了区间1的情况,也记录了区间0的情况,当得到反转命令时就很容易进行转换(把1和0的情况互换即可)。

  这道题还有一点要注意的,就是对于lazy标记更新时,如果得到的命令是0或1,那么区间lazy标记直接变为0或1即可,但对于lazy为2的反转命令的情况需要进行这样的处理:如果当前lazy标记为0,则变为1;如果为1,则变为0;如果为2,则取消标记变为-1;如果为-1,则赋予标记为2。(这个情况没处理好导致自己花了好长时间。)

  代码一如既往的饱满。

View Code
  1 #include <stdio.h>
  2 #include <string.h>
  3 #define lson (cur << 1)
  4 #define rson (cur << 1 | 1)
  5 #define N 100100
  6 
  7 struct node
  8 {
  9     int l, r, c;             // 区间左端点,右端点,长度 
 10     int lsum1, rsum1, msum1; // 左连续1长度,右连续1长度,区间最长连续1长度
 11     int lsum0, rsum0, msum0; // 左连续0长度,右连续0长度,区间最长连续0长度
 12     int sum;                 // 区间1的个数
 13 }tree[N << 2];
 14 
 15 int lazy[N << 2], a[N], n, m;
 16 
 17 inline int max(int x, int y){return x > y ? x : y;}
 18 inline int min(int x, int y){return x < y ? x : y;}
 19 
 20 void transform(int rt)
 21 {
 22     int x, y, z;
 23     x = tree[rt].lsum1;
 24     y = tree[rt].rsum1;
 25     z = tree[rt].msum1;
 26     tree[rt].lsum1 = tree[rt].lsum0;
 27     tree[rt].rsum1 = tree[rt].rsum0;
 28     tree[rt].msum1 = tree[rt].msum0;
 29     tree[rt].lsum0 = x;
 30     tree[rt].rsum0 = y;
 31     tree[rt].msum0 = z;
 32     tree[rt].sum = tree[rt].c - tree[rt].sum;
 33     
 34     if(lazy[rt] == 0)   // 弄清lazy标记的传递
 35         lazy[rt] = 1;
 36     else if(lazy[rt] == 1)
 37         lazy[rt] = 0;
 38     else if(lazy[rt] == 2)
 39         lazy[rt] = -1;
 40     else if(lazy[rt] == -1)
 41         lazy[rt] = 2;
 42 }
 43 
 44 void pushdown(int cur)
 45 {
 46     if(lazy[cur] == 0)
 47     {
 48         lazy[lson] = lazy[rson] = lazy[cur];
 49         tree[lson].lsum1 = tree[lson].rsum1 = tree[lson].msum1 = 0;
 50         tree[rson].lsum1 = tree[rson].rsum1 = tree[rson].msum1 = 0;
 51         tree[lson].lsum0 = tree[lson].rsum0 = tree[lson].msum0 = tree[lson].c;
 52         tree[rson].lsum0 = tree[rson].rsum0 = tree[rson].msum0 = tree[rson].c;
 53         tree[lson].sum = 0;
 54         tree[rson].sum = 0;
 55     }
 56     else if(lazy[cur] == 1)
 57     {
 58         lazy[lson] = lazy[rson] = lazy[cur];
 59         tree[lson].lsum1 = tree[lson].rsum1 = tree[lson].msum1 = tree[lson].c;
 60         tree[rson].lsum1 = tree[rson].rsum1 = tree[rson].msum1 = tree[rson].c;
 61         tree[lson].lsum0 = tree[lson].rsum0 = tree[lson].msum0 = 0;
 62         tree[rson].lsum0 = tree[rson].rsum0 = tree[rson].msum0 = 0;
 63         tree[lson].sum = tree[lson].c;
 64         tree[rson].sum = tree[rson].c;
 65     }
 66     else if(lazy[cur] == 2)
 67     {
 68         transform(lson);
 69         transform(rson);
 70     }
 71     lazy[cur] = -1;
 72 }
 73 
 74 void pushup(int cur)
 75 {
 76     tree[cur].sum = tree[lson].sum + tree[rson].sum;
 77     
 78     tree[cur].lsum1 = tree[lson].lsum1;
 79     tree[cur].rsum1 = tree[rson].rsum1;
 80     tree[cur].msum1 = max(tree[lson].msum1, tree[rson].msum1);
 81     if(tree[lson].lsum1 == tree[lson].c)
 82         tree[cur].lsum1 += tree[rson].lsum1;
 83     if(tree[rson].rsum1 == tree[rson].c)
 84         tree[cur].rsum1 += tree[lson].rsum1;
 85     tree[cur].msum1 = max(tree[cur].msum1, tree[lson].rsum1 + tree[rson].lsum1);
 86 
 87     tree[cur].lsum0 = tree[lson].lsum0;
 88     tree[cur].rsum0 = tree[rson].rsum0;
 89     tree[cur].msum0 = max(tree[lson].msum0, tree[rson].msum0);
 90     if(tree[lson].lsum0 == tree[lson].c)
 91         tree[cur].lsum0 += tree[rson].lsum0;
 92     if(tree[rson].rsum0 == tree[rson].c)
 93         tree[cur].rsum0 += tree[lson].rsum0;
 94     tree[cur].msum0 = max(tree[cur].msum0, tree[lson].rsum0 + tree[rson].lsum0);
 95 }
 96 
 97 void update(int cur, int l, int r, int flag)
 98 {
 99     if(tree[cur].l >= l && tree[cur].r <= r)
100     {
101         if(flag == 0)
102         {
103             lazy[cur] = 0;
104             tree[cur].lsum1 = tree[cur].rsum1 = tree[cur].msum1 = 0;
105             tree[cur].lsum0 = tree[cur].rsum0 = tree[cur].msum0 = tree[cur].c;
106             tree[cur].sum = 0;
107         }
108         else if(flag == 1)
109         {
110             lazy[cur] = 1;
111             tree[cur].lsum1 = tree[cur].rsum1 = tree[cur].msum1 = tree[cur].c;
112             tree[cur].lsum0 = tree[cur].rsum0 = tree[cur].msum0 = 0;
113             tree[cur].sum = tree[cur].c;
114         }
115         else if(flag == 2)
116         {
117             transform(cur);
118         }
119         return ;
120     }
121     pushdown(cur);
122     int mid = (tree[cur].l + tree[cur].r) >> 1;
123     if(mid >= l)
124         update(lson, l, r, flag);
125     if(mid + 1 <= r)
126         update(rson, l, r, flag);
127     pushup(cur);
128 }
129 
130 void query3(int cur, int l, int r, int &ans)
131 {
132     if(tree[cur].l >= l && tree[cur].r <= r)
133     {
134         ans += tree[cur].sum;
135         return ;
136     }
137     pushdown(cur);
138     int mid = (tree[cur].l + tree[cur].r) >> 1;
139     if(mid >= l)
140         query3(lson, l, r, ans);
141     if(mid + 1 <= r)
142         query3(rson, l, r, ans);
143 }
144 
145 int query4(int cur, int l, int r)
146 {
147     if(tree[cur].l >= l && tree[cur].r <= r)
148     {
149         return tree[cur].msum1;
150     }
151     pushdown(cur);
152     int ans = 0;
153     int mid = (tree[cur].l + tree[cur].r) >> 1;
154     if(mid >= l)
155         ans = max(ans, query4(lson, l, r));
156     if(mid < r)
157         ans = max(ans, query4(rson, l, r));
158     ans = max(ans, min(mid - l + 1, tree[lson].rsum1) + min(r - mid, tree[rson].lsum1));
159     return ans;
160 }
161 
162 
163 void build(int cur, int l, int r)
164 {
165     tree[cur].l = l, tree[cur].r = r, tree[cur].c = r - l + 1;
166     lazy[cur] = -1;
167     if(l == r)
168     {
169         if(a[l] == 1)
170         {
171             tree[cur].lsum1 = tree[cur].rsum1 = tree[cur].msum1 = 1;
172             tree[cur].lsum0 = tree[cur].rsum0 = tree[cur].msum0 = 0;
173             tree[cur].sum = 1;
174         }
175         else if(a[l] == 0)
176         {
177             tree[cur].lsum1 = tree[cur].rsum1 = tree[cur].msum1 = 0;
178             tree[cur].lsum0 = tree[cur].rsum0 = tree[cur].msum0 = 1;
179             tree[cur].sum = 0;
180         }
181         return ;
182     }
183     int mid = (l + r) >> 1;
184     build(lson, l, mid);
185     build(rson, mid + 1, r);
186     pushup(cur);
187 }
188 
189 int main()
190 {
191     int i, cas, op, x, y, ans;
192     scanf("%d", &cas);
193     while(cas --)
194     {
195         scanf("%d%d", &n, &m);
196         for(i = 1; i <= n; i ++)
197             scanf("%d", &a[i]);
198         build(1, 1, n);
199         while(m --)
200         {
201             scanf("%d%d%d", &op, &x, &y);
202             ++x, ++y;
203             switch(op)
204             {
205                 case 0:
206                     update(1, x, y, 0);
207                     break;
208                 case 1:
209                     update(1, x, y, 1);
210                     break;
211                 case 2:
212                     update(1, x, y, 2);
213                     break;
214                 case 3:
215                     ans = 0;
216                     query3(1, x, y, ans);
217                     printf("%d\n", ans);
218                     break;
219                 case 4:
220                     printf("%d\n", query4(1, x, y));
221                     break;
222                 default:
223                     break;
224             }
225         }
226     }
227     return 0;
228 }

 

posted @ 2012-10-02 20:00  芒果布丁  阅读(207)  评论(0编辑  收藏  举报