zoukankan      html  css  js  c++  java
  • Hotel [POJ

    Hotel POJ - 3667 T3 D3

    线段树区间修改 、区间合并

    思路:

    1表示当前车位无车,0表示有

    llen 表示当前区间左端点向右连续的1的个数

    rlen 表示当前区间右端点向左连续的1的个数

    sum 表示当前区间最大连续1的个数

    用线段树维护 llen, rlen,sum

    询问时:

    • 若左子树的sum大于查询长度len,递归左子树
    • 若左子树的rlen+右子树的llen大于len,则返回左子树的rlen起点,即为答案
    • 前两种情况都不满足,递归右子树

    参考代码

    /*
                   #########                       
                  ############                     
                  #############                    
                 ##  ###########                   
                ###  ###### #####                  
                ### #######   ####                 
               ###  ########## ####                
              ####  ########### ####               
            #####   ###########  #####             
           ######   ### ########   #####           
           #####   ###   ########   ######         
          ######   ###  ###########   ######       
         ######   #### ##############  ######      
        #######  ##################### #######     
        #######  ##############################    
       #######  ###### ################# #######   
       #######  ###### ###### #########   ######   
       #######    ##  ######   ######     ######   
       #######        ######    #####     #####    
        ######        #####     #####     ####     
         #####        ####      #####     ###      
          #####      ;###        ###      #        
            ##       ####        ####              
    */
    #include<iostream>
    #include<algorithm>
    #include<math.h>
    #define ll long long 
    #define ls (p<<1)
    #define rs ((p<<1)|1)
    #define mid ((t[p].l+t[p].r)>>1) 
    using namespace std;
    int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
    inline void Prin(int x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');}
    const int qs=1e5+7;
    struct Tree{
    	int l,r,llen,rlen,sum,add;
    	#define l(x) t[x].l
    	#define r(x) t[x].r
    	#define llen(x) t[x].llen
    	#define rlen(x) t[x].rlen
    	#define sum(x) t[x].sum
    	#define add(x) t[x].add
    }t[qs<<2];
    
    
    void pushup(int p){
    	llen(p)=llen(ls)+(llen(ls)==r(ls)-l(ls)+1 ? llen(rs) : 0);
    	rlen(p)=rlen(rs)+(rlen(rs)==r(rs)-l(rs)+1 ? rlen(ls) : 0);
    	sum(p)=max(max(sum(ls),sum(rs)),rlen(ls)+llen(rs));
    }
    
    void build(int p,int l,int r){
    	l(p)=l,r(p)=r;
    	add(p)=-1;
    	if(l==r) {
    		llen(p)=rlen(p)=1;
    		sum(p)=1; 
    		return;
    	}
    	build(ls,l,mid);
    	build(rs,mid+1,r);
    	pushup(p);
    }
    
    void down(int p){
    	if(add(p)==-1) return;
    	llen(ls)=rlen(ls)=sum(ls)=(r(ls)-l(ls)+1)*add(p);
    	llen(rs)=rlen(rs)=sum(rs)=(r(rs)-l(rs)+1)*add(p);
    	add(ls)=add(rs)=add(p);
    	add(p)=-1;
    }
    
    void update(int p,int l,int r,int k){
    	if(l<=l(p)&&r>=r(p)){
    		llen(p)=rlen(p)=sum(p)=(r(p)-l(p)+1)*k;
    		add(p)=k;
    		return;
    	}
    	down(p);
    	if(l<=mid) update(ls,l,r,k);
    	if(r>mid) update(rs,l,r,k);
    	pushup(p);
    }
    
    int ask(int p,int len){
    	if(l(p)==r(p)) return 1;
    	down(p);
    	if(sum(ls)>=len) return ask(ls,len);
    	else if(llen(rs)+rlen(ls)>=len) return mid-rlen(ls)+1;
    	else return ask(rs,len);
    	return 0;
    } 
    
    int n,q;
    int main(){
    	n=read(),q=read();
    	build(1,1,n);
    	while(q--){
    		int x,l,len;
    		x=read();
    		if(x==1){
    			len=read();
    			if(sum(1)<len){
    				puts("0");
    				continue;
    			}
    			int ans=ask(1,len);
    			Prin(ans);
    			puts("");
    			update(1,ans,ans+len-1,0);
    		}
    		else {
    			l=read(),len=read();
    			update(1,l,l+len-1,1);
    		}
    	}
    	
    	
    	return 0;
    }
    
    
  • 相关阅读:
    图解Go里面的互斥锁mutex了解编程语言核心实现源码
    day04 NTFS安全权限 | 文件共享服务器
    day03 用户与组管理 | 远程管理
    关于VMware的一些资源|IOS|序列号
    day03 批处理
    day02-IP地址详解
    test1
    simulink产生周期矩形波和8421码
    矩阵连乘问题的算法复杂度的计算--卡塔兰数(Catalan数)的数学推导和近似公式
    找出"吸血鬼数"(Java)
  • 原文地址:https://www.cnblogs.com/Suki-Sugar/p/15139681.html
Copyright © 2011-2022 走看看