zoukankan      html  css  js  c++  java
  • POJ3667 Hotel(线段树)

    这道题和poj1823 一毛一样

    可以参考我的另一个题解

    唯一的区别是,他要找的是最左边的,那么我们自然可以考虑越左越好

    如果当前点的lmax能满足,直接返回

    不然的话,如果当前点的左儿子的tmax满足,就去左节点

    如果是横跨区间的,也直接返回

    如果在右儿子,就去右儿子

    注意,我之前已经特判过不满足的情况,所以一旦进入,就一定满足。

    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<stack>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    const int inf=0x3f3f3f3f;
    struct node{
        int l,r;
        int lazy;
        int tmax;
        int lmax;
        int rmax;
    }tr[N];
    void pushup(int u){
        tr[u].rmax=tr[u<<1|1].rmax;
        if(tr[u<<1|1].lazy==-1)
            tr[u].rmax+=tr[u<<1].rmax;
        tr[u].lmax=tr[u<<1].lmax;
        if(tr[u<<1].lazy==-1)
            tr[u].lmax+=tr[u<<1|1].lmax;
        tr[u].tmax=max(tr[u<<1].rmax+tr[u<<1|1].lmax,max(tr[u<<1].tmax,tr[u<<1|1].tmax));
        if(tr[u<<1].lazy==tr[u<<1|1].lazy)
            tr[u].lazy=tr[u<<1].lazy;
        else{
            tr[u].lazy=0;
        }
    }
    void build(int u,int l,int r){
        if(l==r){
            tr[u]=(node){l,l,-1,1,1,1};
        }
        else{
            tr[u]=(node){l,r,-1};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    void pushdown(int u){
        tr[u<<1].lazy=tr[u<<1|1].lazy=tr[u].lazy;
        if(tr[u].lazy==1){
            tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=0;
            tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=0;
        }
        else{
            tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=tr[u<<1].r-tr[u<<1].l+1;
            tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=tr[u<<1|1].r-tr[u<<1|1].l+1;
        }
        tr[u].lazy=0;
    }
    void modify(int u,int l,int r,int x){
        if(tr[u].l>=l&&tr[u].r<=r){
            tr[u].lazy=x;
            if(x==1){
                tr[u].lmax=tr[u].rmax=tr[u].tmax=0;
            }
            else{
                tr[u].lmax=tr[u].rmax=tr[u].tmax=tr[u].r-tr[u].l+1;
            }
            return ;
        }
        if(tr[u].lazy!=0)
            pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,r,x);
        if(r>mid){
            modify(u<<1|1,l,r,x);
        }
        pushup(u);
    }
    int query(int u,int k){
        if(tr[u].lmax>=k)
            return tr[u].l;
        if(tr[u<<1].tmax>=k)
            return query(u<<1,k);
        if(tr[u<<1].rmax+tr[u<<1|1].lmax>=k)
            return tr[u<<1].r-tr[u<<1].rmax+1;
        return query(u<<1|1,k);
    }
    int main(){
        int n,m;
        cin>>n>>m;
        build(1,1,n);
        int i;
        for(i=1;i<=m;i++){
            int c;
            scanf("%d",&c);
            if(c==1){
                int k;
                scanf("%d",&k);
                if(tr[1].tmax<k){
                    printf("0
    ");
                    continue;
                }
                int tmp=query(1,k);
                printf("%d
    ",tmp);
                modify(1,tmp,tmp+k-1,1);
            }
            else{
                int l,r;
                scanf("%d%d",&l,&r);
                modify(1,l,l+r-1,-1);
            }
        }
    
    }
    View Code
  • 相关阅读:
    sublime text 4 vim 插件配置
    ssh-keygen 的使用
    distribution transaction solution
    bilibili 大数据 视频下载 you-get
    Deepin 20.2.1 安装 MS SQL 2019 容器版本
    【转】使用Linux下Docker部署MSSQL并加载主机目录下的数据库
    【转】You Can Now Use OneDrive in Linux Natively Thanks to Insync
    dotnet 诊断工具安装命令
    Linux 使用 xrandr 设置屏幕分辨率
    【转】CentOS 7.9 2009 ISO 官方原版镜像下载
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12442833.html
Copyright © 2011-2022 走看看