• 【HDOJ】3397 Sequence operation


    线段树的应用,很不错的一道题目。结点属性包括:
    (1)n1:1的个数;
    (2)c1:连续1的最大个数;
    (3)c0:连续0的最大个数;
    (4)lc1/lc0:从区间左边开始,连续1/0的最大个数;
    (5)rc1/rc0:从区间右边开始,连续1/0的最大个数;
    (6)set:置区间为0/1的标记;
    (7)flip:0->1, 1->0的标记。
    采用延迟更新。每当更新set时,flip就置为false;每当更新flip时,其实就是c1/c0, lc1/lc0, rc1/rc0的交换。
    对于询问最长连续1,共包括3种情况:左子树的最长连续1,右子树的最长连续1,以及左子树rc1+右子树lc1(注意有效范围区间)。

      1 /* 3397 */
      2 #include <iostream>
      3 #include <string>
      4 #include <map>
      5 #include <queue>
      6 #include <set>
      7 #include <vector>
      8 #include <algorithm>
      9 #include <cstdio>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <climits>
     13 #include <cctype>
     14 using namespace std;
     15 
     16 #define MAXN 100005
     17 #define lson l, mid, rt<<1
     18 #define rson mid+1, r, rt<<1|1
     19 
     20 typedef struct {
     21     int set;
     22     int n1;
     23     int c1, c0;
     24     int lc1, lc0, rc1, rc0;
     25     bool flip;
     26 } node_t;
     27 
     28 node_t nd[MAXN<<2];
     29 int t, n, m, x;
     30 int op;
     31 
     32 void maintance_set(int op, int len, int rt) {
     33     nd[rt].set = op;
     34     nd[rt].flip = false;
     35     if (op) {
     36         nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = len;
     37         nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = 0;
     38     } else {
     39         nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = 0;
     40         nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = len;
     41     }
     42 }
     43 
     44 void maintance_flip(int len, int rt) {
     45     if (nd[rt].set >= 0)
     46         nd[rt].set = !nd[rt].set;
     47     else
     48         nd[rt].flip = !nd[rt].flip;
     49     nd[rt].n1 = len-nd[rt].n1;
     50     swap(nd[rt].c0, nd[rt].c1);
     51     swap(nd[rt].lc0, nd[rt].lc1);
     52     swap(nd[rt].rc0, nd[rt].rc1);
     53 }
     54 
     55 void PushUp(int l, int r, int rt) {
     56     int lb = rt<<1;
     57     int rb = rt<<1|1;
     58     int mid = (l+r)>>1;
     59     
     60     // update the number of 1
     61     nd[rt].n1 = nd[lb].n1 + nd[rb].n1;
     62     // update the longest continuous 1 and 0 in string
     63     nd[rt].c1 = max(
     64         max(nd[lb].c1, nd[rb].c1),
     65         nd[lb].rc1 + nd[rb].lc1
     66     );
     67     nd[rt].c0 = max(
     68         max(nd[lb].c0, nd[rb].c0),
     69         nd[lb].rc0 + nd[rb].lc0
     70     );
     71     // update the longest continuous 1/0 from left
     72     nd[rt].lc1 = nd[lb].lc1;
     73     nd[rt].lc0 = nd[lb].lc0;
     74     if (nd[lb].lc1 == mid-l+1)
     75         nd[rt].lc1 += nd[rb].lc1;
     76     if (nd[lb].lc0 == mid-l+1)
     77         nd[rt].lc0 += nd[rb].lc0;
     78     // update the longest continuous 1/0 from right
     79     nd[rt].rc1 = nd[rb].rc1;
     80     nd[rt].rc0 = nd[rb].rc0;
     81     if (nd[rb].rc1 == r-mid)
     82         nd[rt].rc1 += nd[lb].rc1;
     83     if (nd[rb].rc0 == r-mid)
     84         nd[rt].rc0 += nd[lb].rc0;
     85 }
     86 
     87 void PushDown(int l, int r, int rt) {
     88     int lb = rt<<1;
     89     int rb = rt<<1|1;
     90     int mid = (l+r)>>1;
     91     
     92     if (nd[rt].set >= 0) {
     93         // maintance_set lson & rson
     94         maintance_set(nd[rt].set, mid-l+1, lb);
     95         maintance_set(nd[rt].set, r-mid, rb);
     96         nd[rt].set = -1;
     97     }
     98     if (nd[rt].flip) {
     99         // maintance_flip lson & rson
    100         maintance_flip(mid-l+1, lb);
    101         maintance_flip(r-mid, rb);
    102         nd[rt].flip = false;
    103     }
    104 }
    105 
    106 void build(int l, int r, int rt) {
    107     nd[rt].set = -1;
    108     nd[rt].flip = false;
    109     if (l == r) {
    110         scanf("%d", &x);
    111         nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = x;
    112         nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = !x;
    113         return ;
    114     }
    115     int mid = (l+r)>>1;
    116     build(lson);
    117     build(rson);
    118     PushUp(l, r, rt);
    119 }
    120 
    121 // update to set [L, R] to op
    122 void update1(int L, int R, int l, int r, int rt) {
    123     if (L<=l && R>=r) {
    124         maintance_set(op, r-l+1, rt);
    125         return ;
    126     }
    127     int mid = (l+r)>>1;
    128     PushDown(l, r, rt);
    129     if (L <= mid)
    130         update1(L, R, lson);
    131     if (R > mid)
    132         update1(L, R, rson);
    133     PushUp(l, r, rt);
    134 }
    135 
    136 // update to flip [L, R] one
    137 void update2(int L, int R, int l, int r, int rt) {
    138     if (L<=l && R>=r) {
    139         maintance_flip(r-l+1, rt);
    140         return ;
    141     }
    142     int mid = (l+r)>>1;
    143     PushDown(l, r, rt);
    144     if (L <= mid)
    145         update2(L, R, lson);
    146     if (R > mid)
    147         update2(L, R, rson);
    148     PushUp(l, r, rt);
    149 }
    150 
    151 // query the sum of 1 in [L, R]
    152 int query3(int L, int R, int l, int r, int rt) {
    153     if (L<=l && R>=r)
    154         return nd[rt].n1;
    155     int mid = (l+r)>>1;
    156     PushDown(l, r, rt);
    157     int ret = 0;
    158     if (L <= mid)
    159         ret += query3(L, R, lson);
    160     if (R > mid)
    161         ret += query3(L, R, rson);
    162     return ret;
    163 }
    164 
    165 // query the longest continous 1 in [L, R]
    166 int query4(int L, int R, int l, int r, int rt) {
    167     if (L<=l && R>=r)
    168         return nd[rt].c1;
    169     int mid = (l+r)>>1;
    170     PushDown(l, r, rt);
    171     int ret;
    172     if (L > mid) {
    173         return query4(L, R, rson);
    174     } else if (R <= mid) {
    175         return query4(L, R, lson);
    176     } else {
    177         ret = max(
    178             query4(L, R, lson),
    179             query4(L, R, rson)
    180         );
    181         int rc1 = nd[rt<<1].rc1;
    182         int lc1 = nd[rt<<1|1].lc1;
    183         if (rc1 > mid-L+1)
    184             rc1 = mid-L+1;
    185         if (lc1 > R-mid)
    186             lc1 = R-mid;
    187         ret = max(
    188             rc1 + lc1,
    189             ret
    190         );
    191     }
    192     return ret;
    193 }
    194 
    195 int main() {
    196     int i, j, k;
    197     int a, b;
    198     
    199     #ifndef ONLINE_JUDGE
    200         freopen("data.in", "r", stdin);
    201         freopen("data.out", "w", stdout);
    202     #endif
    203     
    204     scanf("%d", &t);
    205     while (t--) {
    206         scanf("%d %d", &n, &m);
    207         build(1, n, 1);
    208         while (m--) {
    209             scanf("%d %d %d", &op, &a, &b);
    210             ++a;
    211             ++b;
    212             if (op == 0) {
    213                 update1(a, b, 1, n, 1);
    214             } else if (op == 1) {
    215                 update1(a, b, 1, n, 1);
    216             } else if (op == 2) {
    217                 update2(a, b, 1, n, 1);
    218             } else if (op == 3) {
    219                 k = query3(a, b, 1, n, 1);
    220                 printf("%d
    ", k);
    221             } else {
    222                 k = query4(a, b, 1, n, 1);
    223                 printf("%d
    ", k);
    224             }
    225         }
    226     }
    227     
    228     return 0;
    229 }
  • 相关阅读:
    数据算法之汉诺塔
    Mvc模板页
    mvc局部视图
    Area区域
    mvc之文件下载
    MVC过滤器
    MVC_Ajax请求
    MVC之校验
    Json&Razor&控制器
    抓包分析,tcpdump 和 wireshark 配合使用的简单尝试
  • 原文地址:https://www.cnblogs.com/bombe1013/p/4396244.html
Copyright © 2020-2023  润新知