zoukankan      html  css  js  c++  java
  • POJ-3667 线段树区间合并入门题

    题意:长度为n的区间,m个操作,一开始都是0

    1 x表示求出长度为x的0的连续区间的最左端,并把这个区间变成1

    2 x y表示将区间[x,y]变成0

    线段树的区间合并第一题:

    每次维护左端连续区间长度ls、右端连续区间长度rs,最大连续长度ms

    区间合并的注意点主要在push up操作:

    每次更新了一段区间之后向上更新,首先,父区间的ls继承左子树的ls,父区间的rs继承右子树的rs

    然后就是重点:左右区间合并之后中间部分可能是连续的!!!

    所以:如果整个左、右子区间都是“满的”,父区间的ls和rs分别就要连到另一侧去

    最后,父区间的ms要比较三个值:ls、rs和【左区间的rs加上右区间的ls】,这里画个图或者联系归并排序就可以看出来

    贴一下模板以后不手敲了,怕出错

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define lid id << 1
     4 #define rid id << 1 | 1
     5 using namespace std;
     6 
     7 const int mx = 50010;
     8 
     9 struct tree{
    10     int l, r;
    11     int ls, rs, ms;
    12     int lazy;
    13 }tree[mx<<2];
    14 
    15 void build(int l, int r, int id){
    16     tree[id].l = l;
    17     tree[id].r = r;
    18     tree[id].ls = tree[id].rs = tree[id].ms = r-l+1;
    19     tree[id].lazy = -1;
    20     if (l == r) return;
    21     int mid = (l+r) >> 1;
    22     build(l, mid, lid);
    23     build(mid+1, r, rid);
    24 }
    25 
    26 void pushdown(int id){
    27     if (tree[id].lazy != -1){
    28         tree[lid].lazy = tree[rid].lazy = tree[id].lazy;
    29         tree[lid].ls = tree[lid].rs = tree[lid].ms = tree[id].lazy ? 0 : tree[lid].r-tree[lid].l+1;
    30         tree[rid].ls = tree[rid].rs = tree[rid].ms = tree[id].lazy ? 0 : tree[rid].r-tree[rid].l+1;
    31         tree[id].lazy = -1;
    32     }
    33 }
    34 
    35 void pushup(int id){
    36     tree[id].ls = tree[lid].ls;
    37     tree[id].rs = tree[rid].rs;
    38     int mid = (tree[id].l + tree[id].r) >> 1;
    39     if (tree[id].ls == mid-tree[id].l+1) tree[id].ls += tree[rid].ls;
    40     if (tree[id].rs == tree[id].r-mid) tree[id].rs += tree[lid].rs;
    41     tree[id].ms = max(max(tree[lid].ms, tree[rid].ms), tree[lid].rs+tree[rid].ls);
    42 }
    43 
    44 void upd(int l, int r, int id, bool x){
    45     if (tree[id].l == l && tree[id].r == r){
    46         tree[id].lazy = x;
    47         tree[id].ls = tree[id].rs = tree[id].ms = x ? 0 : r-l+1;
    48         return;
    49     }
    50     pushdown(id);
    51     int mid = (tree[id].l + tree[id].r) >> 1;
    52     if (r <= mid) upd(l, r, lid, x);
    53     else if (mid < l) upd(l, r, rid, x);
    54     else {
    55         upd(l, mid, lid, x);
    56         upd(mid+1, r, rid, x);
    57     }
    58     pushup(id);
    59 }
    60 
    61 int query(int l, int r, int id, int x){
    62     if (l == r) return l;
    63     pushdown(id);
    64     int mid = (l+r) >> 1;
    65     if (tree[lid].ms >= x) return query(l, mid, lid, x);
    66     else if (tree[lid].rs + tree[rid].ls >= x) return mid-tree[lid].rs+1;
    67     return query(mid+1, r, rid, x);
    68 }
    69 
    70 int main(){
    71     int n, m;
    72     scanf("%d%d", &n, &m);
    73     build(1, n, 1);
    74     while (m--){
    75         int op, a, b;
    76         scanf("%d%d", &op, &a);
    77         if (op == 1){
    78             if (tree[1].ms < a) printf("0
    ");
    79             else {
    80                 b = query(1, n, 1, a);
    81                 printf("%d
    ", b);
    82                 upd(b, b+a-1, 1, 1);
    83             }
    84         }
    85         else {
    86             scanf("%d", &b);
    87             upd(a, a+b-1, 1, 0);
    88         }
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    PouchDB:一款受CouchDB启发的离线Web数据库
    如何使用JPA注解映射枚举类型
    重新排列参数
    sql不同数据处理方式完成同一处理结果对日志增长的影响
    那些让我念念不忘的 Firefox 扩展
    Linux现可运行于Windows Azure上
    Vector Fabrics推出多核软件优化工具Pareon
    分解公式 sql
    sql树形数据生成xml
    Microsoft .NET终于提供了一个通用的Zip库
  • 原文地址:https://www.cnblogs.com/QAQorz/p/9379681.html
Copyright © 2011-2022 走看看