zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    系统右键菜单添加剪贴板清空项(隐藏DOS窗口)
    C++实现黄金分割数列(斐波纳奇数列)(非递归)
    vbs让电脑发音说话
    修改远程桌面端口号.bat
    C#实现鸽巢排序
    C++用递归方式实现在对不更改随机数组的情况下查找最大值
    C# 实现 微软WebRequestMethods.Ftp类中的FTP操作功能
    C# “快捷方式” 实现程序开机启动
    C++ DateTime 结构
    C# UDP 连接通信 简单示例
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2710511.html
Copyright © 2011-2022 走看看