HDU 1540 区间合并线段树

题目大意:

就是给定一堆位置,进行删除还原,最后找到 t 位置上的最大连续位置

 

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <iostream>

  4 

  5 using namespace std;

  6 const int N = 50005;

  7 

  8 struct Node{

  9     int l , r , ml , mr , ma; //ml左最长,mr右最长,ma总最长

 10 }tree[N<<2];

 11 

 12 void build(int o , int l , int r)

 13 {

 14     tree[o].l = l;

 15     tree[o].r = r;

 16     tree[o].ml = r - l + 1;

 17     tree[o].mr = r - l + 1;

 18     tree[o].ma = r - l + 1;

 19     int m = (l + r) / 2;

 20     if(l == r) return ;

 21     build(o<<1 , l , m);

 22     build(o<<1|1 , m+1 , r);

 23 }

 24 

 25 void push_up(int o)

 26 {

 27     int ls = o<<1 , rs = o<<1|1;

 28     tree[o].ml = tree[ls].ml;

 29     tree[o].mr = tree[rs].mr;

 30 

 31     if(tree[ls].ml == (tree[ls].r - tree[ls].l + 1))

 32         tree[o].ml = tree[ls].ml + tree[rs].ml;

 33 

 34     if(tree[rs].mr == (tree[rs].r - tree[rs].l + 1))

 35         tree[o].mr = tree[ls].mr + tree[rs].mr;

 36 

 37     tree[o].ma = max(tree[ls].mr + tree[rs].ml , tree[rs].ma);

 38     tree[o].ma = max(tree[ls].ma , tree[o].ma);

 39 }

 40 

 41 void update(int o , int t , int v)

 42 {

 43     if(tree[o].l == tree[o].r){

 44         if(v == 1) tree[o].ma = tree[o].ml = tree[o].mr = 1;

 45         else tree[o].ma = tree[o].ml = tree[o].mr = 0;

 46         return ;

 47     }

 48     int ls = o<<1 , rs = o<<1|1;

 49     int m = (tree[o].l + tree[o].r) / 2;

 50 

 51     if(t <= m) update(ls , t , v);

 52     else update(rs , t , v);

 53     //要等下层更新完才能递归回去更新上层

 54     push_up(o);

 55 }

 56 

 57 int query(int o , int t)

 58 {

 59     int ls = o<<1 , rs = o<<1|1 , m = (tree[o].l + tree[o].r) / 2;

 60     if(tree[o].l == tree[o].r || tree[o].ma == 0 || tree[o].ma == tree[o].r - tree[o].l + 1)

 61         return tree[o].ma;

 62 

 63     if(t <= m){

 64         /*此时t属于左子树,那么存在t只属于左子树区间,和属于左右子树合并的区间

 65         ,弱属于合并的区间,那么要保证,t到左子树右端点形成的连续的个数要小于

 66         左子树最大右端连续和

 67         也就是 m - t + 1 <= tree[ls].mr (这里m也等于tree[ls].r)

 68         */

 69         if(t >= tree[ls].r - tree[ls].mr + 1)

 70             return query(ls , t) + query(rs , m+1);

 71         else return query(ls , t);

 72     }else{

 73         if(t <= tree[rs].l + tree[rs].ml - 1)

 74             return query(ls , m) + query(rs , t);

 75         else query(rs , t);

 76     }

 77 }

 78 

 79 int que[N] , top;

 80 

 81 int main()

 82 {

 83  //   freopen("a.in" , "r" , stdin);

 84     int n,m;

 85     char str[10];

 86     int x;

 87     while(scanf("%d%d",&n,&m)!=EOF){

 88         build(1,1,n);

 89         top=0;

 90         while(m--)

 91         {

 92             scanf("%s",str);

 93             if(str[0]=='D'){

 94                 scanf("%d",&x);

 95                 que[top++]=x;

 96                 update(1,x,0);

 97             }

 98             else if(str[0]=='Q'){

 99                 scanf("%d",&x);

100                 printf("%d\n",query(1,x));

101             }

102             else{

103                 if(x>0){

104                     x=que[--top];

105                     update(1,x,1);

106                 }

107             }

108         }

109     }

110     return 0;

111 }

 

你可能感兴趣的:(HDU)