• 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
    ",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 }
  • 相关阅读:
    Oracle序列使用:建立、删除
    struts1.x入门
    SQL的四种连接-左外连接、右外连接、内连接、全连接
    eclipse更改文件编码方式
    使用links方式安装Eclipse插件
    JAVA:Eclipse代码自动提示
    MyEclipse注释配置
    全面理解SQL
    一秒去除Win7快捷方式箭头
    Eclipse快捷键大全(转载)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4190314.html
Copyright © 2020-2023  润新知