• hdu1540 区间合并模板(点修改及查询)


    传送门::http://acm.hdu.edu.cn/showproblem.php?pid=1540

    题意:有n个连在一起的地道,接下来m个操作,D x 代表摧毁 x 地道;R 代表修建最近一次摧毁的地道;R x 查询与x地道相连的地道有多少个(最大连续区间长度)

     思路::线段树

    线段树区间合并问题,维护三个变量

    llen ::从左端点开始的最大连续区间长度

    rlen::从右端点开始的最大连续区间长度

    mlen::该区间的最大连续长度

    如何维护呢?

    双亲的llen 如果它左孩子的整个区间连续,llen=左孩子llen+右孩子的llen

    双亲的rlen 如何它右孩子的整个区间来连续,rlen=右孩子rlen+左孩子的rlen

    双亲的mlen  左孩子的mlen,右孩子的mlen,左孩子的rlen+右孩子的llen 三者最大值

    至于查询的话也比较简单

       如果它在左孩子rlen中,结果就是左孩子derlen+右孩子的llen,反之就在左孩子里

      如果他在右孩子的llen中,结果就是右孩子的llen+左孩子的rllen反之就在右孩子里

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=5e4+5;
     5 
     6 int llen[maxn<<2],rlen[maxn<<2],mlen[maxn<<2];
     7 
     8 stack<int>s;
     9 
    10 void pushup(int rt,int m)
    11 {
    12     mlen[rt]=max(max(mlen[2*rt],mlen[2*rt+1]),rlen[2*rt]+llen[2*rt+1]);
    13     llen[rt]=llen[2*rt];
    14     rlen[rt]=rlen[2*rt+1];
    15     if(llen[2*rt]==m-(m>>1))
    16         llen[rt]+=llen[2*rt+1];
    17     if(rlen[2*rt+1]==(m>>1))
    18         rlen[rt]+=rlen[2*rt];
    19 }
    20 void build(int l,int r,int rt)
    21 {
    22     llen[rt]=rlen[rt]=mlen[rt]=r-l+1;
    23     if(l==r){return ;}
    24     int mid=(l+r)>>1;
    25     build(l,mid,2*rt);
    26     build(mid+1,r,2*rt+1);
    27 }
    28 void update(int l,int r,int rt,int pos,int k)
    29 {
    30     if(l==r){
    31         llen[rt]=rlen[rt]=mlen[rt]=k;
    32         return ;
    33     }
    34     int mid=(l+r)>>1;
    35     if(pos<=mid)
    36         update(l,mid,2*rt,pos,k);
    37     else
    38         update(mid+1,r,2*rt+1,pos,k);
    39     pushup(rt,r-l+1);
    40 }
    41 int query(int l,int r,int rt,int pos)
    42 {
    43     if(mlen[rt]==0||mlen[rt]==(r-l+1)){
    44         return mlen[rt];
    45     }
    46     int mid=(l+r)>>1;
    47     if(pos<=mid){
    48         if(pos>=mid-rlen[2*rt]+1)
    49             return rlen[2*rt]+llen[2*rt+1];
    50         else
    51             return query(l,mid,2*rt,pos);
    52     }
    53     else{
    54         if(pos<=mid+llen[2*rt+1])
    55             return llen[2*rt+1]+rlen[2*rt];
    56         else
    57             return query(mid+1,r,2*rt+1,pos);
    58     }
    59 }
    60 int main()
    61 {
    62     int n,m;
    63     while(~scanf("%d%d",&n,&m)){
    64     build(1,n,1);
    65     while(m--)
    66     {
    67         char op;int k;
    68         scanf(" %c",&op);
    69         if(op=='R'&&!s.empty()){
    70             update(1,n,1,s.top(),1);
    71             s.pop();
    72         }
    73         else if(op=='D'){
    74             scanf("%d",&k);
    75             s.push(k);
    76             update(1,n,1,k,0);
    77         }
    78         else {
    79             scanf("%d",&k);
    80             printf("%d
    ",query(1,n,1,k));
    81         }
    82     }
    83     }
    84     return 0;
    85 }
    纵使单枪匹马,也要勇闯天涯
  • 相关阅读:
    个人理解闭包
    个人理解回调
    在网站中设置一个分享到功能
    在lua中从一个字符串中移除空间源码
    成都实行积分落户
    unity3D客户端框架
    skynet对Windows环境支持的版本:Windows版skynet
    超期羁押
    资料
    媒体电话
  • 原文地址:https://www.cnblogs.com/sj-gank/p/11842625.html
Copyright © 2020-2023  润新知