zoukankan      html  css  js  c++  java
  • 最大连续区间(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;
    }
    
  • 相关阅读:
    机器学习-数据与特征工程
    机器学习-聚类(clustering)算法:K-means算法
    机器学习-回归中的相关度和R平方值
    机器学习-非线性回归(Logistic Regression)及应用
    机器学习-多元线性回归(一)
    机器学习-简单线性回归(二)
    MVC,MVP,MVVM
    Git从入门到熟练
    NSNotificationCenter
    FMDB的线程安全
  • 原文地址:https://www.cnblogs.com/chilkings/p/11946244.html
Copyright © 2011-2022 走看看