zoukankan      html  css  js  c++  java
  • [HDOJ3911]Black And White(线段树,区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3911

    题意:一个01串,两种操作:

    0 a b:查询[a,b]内连续1的最长长度。

    1 a b:翻转[a,b]内的所有数字(0变1,1变0)。

    更新操作落实到具体数字,这时候不能莽直接更新数字对吧,我们要考虑翻转这个操作如何跟懒惰标记对上。让我们可以通过懒惰标记间接更新而不是直接每次更新到叶子。

    我们知道一个性质:翻转偶数次相当于没有翻转,那么懒惰标记就来标记翻转次数的奇偶吧,假如是偶数次,那么不需要往下更新了。但是这样的话偶数次解决了,奇数次岂不是还要更新。我们要求连续的1的长度,需要维护一组1的长度(从左起最长、从右起最长、区间内最长),那么再对应地维护一组0的长度,反转的时候相当于这两组数字的交换,每次更新再pushup就没有问题了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define lrt rt << 1
     5 #define rrt rt << 1 | 1
     6 typedef struct Node {
     7     int l, r, v;
     8     int lone, sone, rone;
     9   int lzero, szero, rzero;
    10 }Node;
    11 const int maxn = 100100;
    12 int cmd;
    13 int n, q;
    14 int x[maxn];
    15 Node seg[maxn<<4];
    16 
    17 void pushUP(int rt, int len) {
    18   seg[rt].lone = seg[lrt].lone; seg[rt].rone = seg[rrt].rone;
    19   seg[rt].lzero = seg[lrt].lzero; seg[rt].rzero = seg[rrt].rzero;
    20   if(seg[rt].lone == len-len/2) seg[rt].lone += seg[rrt].lone;
    21   if(seg[rt].rone == len/2) seg[rt].rone += seg[lrt].rone;
    22   if(seg[rt].lzero == len-len/2) seg[rt].lzero += seg[rrt].lzero;
    23   if(seg[rt].rzero == len/2) seg[rt].rzero += seg[lrt].rzero;
    24   seg[rt].sone = max(seg[lrt].sone, seg[rrt].sone);
    25   seg[rt].sone = max(seg[rt].sone, seg[lrt].rone+seg[rrt].lone);
    26   seg[rt].szero = max(seg[lrt].szero, seg[rrt].szero);
    27   seg[rt].szero = max(seg[rt].szero, seg[lrt].rzero+seg[rrt].lzero);
    28 }
    29 
    30 void pushDOWN(int rt) {
    31   if(seg[rt].v) {
    32     seg[rt].v = 0;
    33     seg[lrt].v = !seg[lrt].v;
    34     seg[rrt].v = !seg[rrt].v;
    35     swap(seg[lrt].lone, seg[lrt].lzero);
    36     swap(seg[lrt].rone, seg[lrt].rzero);
    37     swap(seg[lrt].sone, seg[lrt].szero);
    38     swap(seg[rrt].lone, seg[rrt].lzero);
    39     swap(seg[rrt].rone, seg[rrt].rzero);
    40     swap(seg[rrt].sone, seg[rrt].szero);
    41   }
    42 }
    43 
    44 void build(int l, int r, int rt) {
    45   seg[rt].l = l; seg[rt].r = r; seg[rt].v = 0;
    46   if(l == r) {
    47     seg[rt].lone = seg[rt].rone = seg[rt].sone = (x[l] == 0) ? 0 : 1;
    48     seg[rt].lzero = seg[rt].rzero = seg[rt].szero = (x[l] == 1) ? 0 : 1;
    49     return;
    50   }
    51   int mid = (l + r) >> 1;
    52   build(l, mid, lrt);
    53   build(mid+1, r, rrt);
    54   pushUP(rt, r-l+1);
    55 }
    56 
    57 void update(int L, int R, int rt) {
    58   if(L <= seg[rt].l && seg[rt].r <= R) {
    59     swap(seg[rt].lone, seg[rt].lzero);
    60     swap(seg[rt].rone, seg[rt].rzero);
    61     swap(seg[rt].sone, seg[rt].szero);
    62     seg[rt].v = !seg[rt].v;
    63     return;
    64   }
    65   pushDOWN(rt);
    66   int mid = (seg[rt].l + seg[rt].r) >> 1;
    67   if(L <= mid) update(L, R, lrt);
    68   if(mid < R) update(L, R, rrt);
    69   pushUP(rt, seg[rt].r-seg[rt].l+1);
    70 }
    71 
    72 int query(int L, int R, int rt) {
    73   if(L == seg[rt].l && R == seg[rt].r) return seg[rt].sone;
    74   pushDOWN(rt);
    75   int mid = (seg[rt].l + seg[rt].r) >> 1;
    76   if(mid >= R) return query(L, R, lrt);
    77   else if(mid + 1 <= L) return query(L, R, rrt);
    78   else {
    79     int tmp = max(query(L, mid, lrt), query(mid+1, R, rrt));
    80     tmp = max(tmp, min(seg[lrt].rone,mid-L+1)+min(seg[rrt].lone,R-mid));
    81     return tmp;
    82   }
    83 }
    84 
    85 int main() {
    86   //freopen("in", "r", stdin);
    87   int a, b;
    88   while(~scanf("%d", &n)) {
    89     for(int i = 1; i <= n; i++) scanf("%d", &x[i]);
    90     build(1, n, 1);
    91     scanf("%d", &q);
    92     while(q--) {
    93       scanf("%d %d %d", &cmd, &a, &b);
    94       if(cmd == 0) printf("%d
    ", query(a, b, 1));
    95       else update(a, b, 1);
    96     }
    97   }
    98   return 0;
    99 }
  • 相关阅读:
    栈和队列的存储结构、线性结构和非线性结构
    java 将一个有大量数据的list集合分成指定大小的list集合
    Java和jdbc实现数据库操作的基础例子
    解决连接Oracle 11g报ORA-01034和ORA-27101的错误和报ORA-00119和ORA-00132这个问题
    Java语言类的特性
    Java类与对象
    Java中的字符串(String)
    Java数组
    Java中的流程控制
    Java中的运算符与表达式
  • 原文地址:https://www.cnblogs.com/kirai/p/5954591.html
Copyright © 2011-2022 走看看