• P2894 [USACO08FEB]Hotel G


    Rose

    用维护区间最长连续1的方法就可以维护

    但是还要维护一下最左边,不过这问题不大

    维护一个区间最长连续子段,不在意位置就可以了

    然后就可以在查询的时候,先看一看在不在左边,在看一看在不在中间,最后看一看在不在右边

    就解决了

    可见学线段树靠背模板是不行的

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<stack>
    #include<map>
    #define lll long long
    using namespace std;
    int n,m;
    int x,y;
    struct t{
    	int lm;
    	int rm;
    	int sum;
    	int l;
    	int lazy;
    }tr[500000];
    // f=1入住 
    void pushdown(int ro){
    	if(tr[ro].lazy==1){
    		tr[ro<<1].lm=tr[ro<<1].rm=tr[ro<<1].sum=0;
    		tr[ro<<1].lazy=1;
    		tr[ro<<1|1].lm=tr[ro<<1|1].rm=tr[ro<<1|1].sum=0;
    		tr[ro<<1|1].lazy=1;
    		tr[ro].lazy=0;
    	}
    	if(tr[ro].lazy==2){
    		tr[ro<<1].lm=tr[ro<<1].rm=tr[ro<<1].sum=tr[ro<<1].l;
    		tr[ro<<1].lazy=2;
    		tr[ro<<1|1].lm=tr[ro<<1|1].rm=tr[ro<<1|1].sum=tr[ro<<1|1].l;
    		tr[ro<<1|1].lazy=2;
    		tr[ro].lazy=0;
    	}
    }
    void pushup(int ro){
    	tr[ro].sum=max(tr[ro<<1].sum,max(tr[ro<<1|1].sum,tr[ro<<1].rm+tr[ro<<1|1].lm));
    	tr[ro].lm=tr[ro<<1].sum==tr[ro<<1].l?tr[ro<<1].sum+tr[ro<<1|1].lm:tr[ro<<1].lm;
    	tr[ro].rm=tr[ro<<1|1].sum==tr[ro<<1|1].l?tr[ro<<1|1].sum+tr[ro<<1].rm:tr[ro<<1|1].rm;
    }
    void add(int ro,int l,int r,int L,int R,int f){
    	if(L<=l&&r<=R){
    		if(f==1){
    			tr[ro].lm=tr[ro].rm=tr[ro].sum=0;
    			tr[ro].lazy=1;
    		}else{
    			tr[ro].lm=tr[ro].rm=tr[ro].sum=tr[ro].l;
    			tr[ro].lazy=2;
    		}
    		return ;
    	}
    	pushdown(ro);
    	int mid=(l+r)>>1;
    	if(L<=mid) add(ro<<1,l,mid,L,R,f);
    	if(R>mid) add(ro<<1|1,mid+1,r,L,R,f);
    	pushup(ro);
    }
    int que(int ro,int l,int r){
    	if(l==r) return l;
    	pushdown(ro);
    	int mid=(l+r)>>1;
    	if(tr[ro<<1].sum>=y){
    		return que(ro<<1,l,mid);
    	}else
    		if(tr[ro<<1].rm+tr[ro<<1|1].lm>=y){
    			return mid-tr[ro<<1].rm+1;
    		}
    	else{
    		return que(ro<<1|1,mid+1,r);
    	}
    }
    void ini(int ro,int l,int r){
    	if(l==r){
    		tr[ro].l=1;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	tr[ro].l=(r-l+1);
    	ini(ro<<1,l,mid);
    	ini(ro<<1|1,mid+1,r);
    }
    int z;
    int main(){
    	scanf("%d%d",&n,&m);
    	ini(1,1,n);
    	add(1,1,n,1,n,2);
    	while(m--){
    		scanf("%d%d",&x,&y);
    		if(x==1){
    			if(tr[1].sum>=y){
    				int l=que(1,1,n);
    				cout<<l<<endl;
    				add(1,1,n,l,l+y-1,1);
    			}else{
    				cout<<0<<endl;
    			}
    		}else{
    			scanf("%d",&z);
    			add(1,1,n,y,y+z-1,2);
    		}
    		
    	}
    	return 0;
    }
    	
    
    
  • 相关阅读:
    GitHub入门之一:使用github下载项目
    Android Fragment 真正的完全解析(下)
    Android Fragment 真正的完全解析(上)
    c# 发送邮件
    SmartThreadPool
    虚拟机
    相关系数
    为枚举类型添加说明 zt
    MD5
    hashcode
  • 原文地址:https://www.cnblogs.com/For-Miku/p/15368511.html
Copyright © 2020-2023  润新知