• 最大连续区间(HDU-1540)


    HDU1540

    线段树最大连续区间。

    给定长度为n的数组,m次操作。

    操作D,删除给定节点。

    操作R,恢复最后一个删除的节点。

    操作Q,询问给定节点的最大连续区间

    维护三个值,区间的最大左连续区间,最大右连续区间,最大连续区间

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <stack>
    using namespace std;
    typedef long long ll;
    const int maxn = 50000 + 5;
    
    #define lson l,m,st<<1
    #define rson m+1,r,st<<1|1
    
    int treelmax[maxn<<2];
    int treermax[maxn<<2];
    int len[maxn<<2]; 
    
    void build(int l,int r,int st)
    {
        len[st]=r-l+1;
        if(l==r) 
        {
            treelmax[st]=1;treermax[st]=1;
            return ;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        treelmax[st]=len[st]; //初始化的值全为区间长度
        treermax[st]=len[st];
    }
    
    void UpdataDes(int x,int l,int r,int st)  //破坏
    {
        if(l==x&&r==x)
        {
            treelmax[st]=0; treermax[st]=0;len[st]=0; return;
        }
        int m=(l+r)>>1;
        if(x<=m) UpdataDes(x,lson);
        else  UpdataDes(x,rson); //if(x>m)
        treelmax[st]=treelmax[st<<1]==(m-l+1)?treelmax[st<<1]+treelmax[st<<1|1]:treelmax[st<<1]; //判断左儿子的最大左连续区间是否等于左儿子区间长度,如果等于,那么父亲的最大左连续区间就等于左儿子的区间长度加上右儿子右最大左区间连续长度
        treermax[st]=treermax[st<<1|1]==(r-m)?treermax[st<<1|1]+treermax[st<<1]:treermax[st<<1|1];
       len[st]=max(max(treelmax[st<<1],treermax[st<<1|1]),treermax[st<<1]+treelmax[st<<1|1]);
        //父节点的最大连续长度等于 左儿子最大左连续区间 右儿子最大右连续区间 左儿子最大右连续区间加上右儿子最大左连续区间  中的最大值
    }
    
    void UpdataRec(int x,int l,int r,int st)  //修复
    {
        if(l==x&&r==x)
        {
            treelmax[st]=1; treermax[st]=1;len[st]=1; return ;
        }
        int m=(l+r)>>1;
        if(x<=m) UpdataRec(x,lson);
        else  UpdataRec(x,rson); //if(x>m)
        treelmax[st]=treelmax[st<<1]==(m-l+1)?treelmax[st<<1]+treelmax[st<<1|1]:treelmax[st<<1];
        treermax[st]=treermax[st<<1|1]==(r-m)?treermax[st<<1|1]+treermax[st<<1]:treermax[st<<1|1];
        len[st]=max(max(treelmax[st<<1],treermax[st<<1|1]),treermax[st<<1]+treelmax[st<<1|1]);
        //pushup; 
    }
    
    int query(int x,int l,int r,int st)
    {
        if(l==r||len[st]==0||len[st]==r-l+1)
        return len[st];
        int m=(l+r)>>1;
        if(x<=m)  //x在左儿子区间内
        {
            if(x>=m-treermax[st<<1]+1)  //x在左儿子的右连续区间内
            return treermax[st<<1]+treelmax[st<<1|1];  //左儿子右连续
            //return len[st<<1];
            else //x在左儿子的左连续区间内
            return query(x,lson); 
        }
        else    //x在右儿子区间内
        {
            if(x<m+1+treelmax[st<<1|1])    //x在右儿子的左连续区间
            return treermax[st<<1]+treelmax[st<<1|1];    //左儿子的右连续加上右儿子的左连续
            //return len[st<<1|1];
            else  //x在右儿子的右连续区间
            return query(x,rson);
        }
    }
    
    int main() 
    {
        int n,m;
        char ope[5];
        int x;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            build(1,n,1);
            stack<int> destroy;
            while(m--)
            {
                scanf("%s",ope);
                if(ope[0]=='D')
                {
                    scanf("%d",&x);
                    UpdataDes(x,1,n,1);
                    destroy.push(x);
                }
                else if(ope[0]=='R')
                {
                    if(destroy.empty()) continue;
                    x=destroy.top();
                    UpdataRec(x,1,n,1);
                    destroy.pop();
                }
                else
                {
                    scanf("%d",&x);
                    printf("%d
    ",query(x,1,n,1));
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    wpf写的httpget请求
    c#的反射机制
    C#中所有的类都继承自哪个类
    使用c#创建windows的桌面的自启服务
    工厂模式的三种实现,就这么简单!
    Github上的沙雕项目,玩100遍都不够
    代理模式的种类、原理及各种实例详解
    面试官问:HashMap在并发情况下为什么造成死循环?一脸懵
    Oracle中 COUNT(count(*))语法
    jquery如何获取当前时间
  • 原文地址:https://www.cnblogs.com/chilkings/p/11946244.html
Copyright © 2020-2023  润新知