zoukankan      html  css  js  c++  java
  • POJ 3667

    维护左连续,右连续区间最大值,同时维护区间内最大的连续区间值。同时是使用标记法完成。很强大。

    注意出现的状态-1,很巧妙,代表该结点不能再下传了,即不符合下传条件。

    #include <cstdio>  
    #include <cstring>  
    #include <cctype>  
    #include <algorithm>  
    using namespace std;  
       
    const int maxn = 55555;  
    int lsum[maxn<<2] , rsum[maxn<<2] , msum[maxn<<2];  
    int cover[maxn<<2]; 
    
    void build(int rt,int l,int r){
    	cover[rt]=-1;
    	lsum[rt]=rsum[rt]=msum[rt]=r-l+1;
    	if(l==r) return;
    	int m=(l+r)>>1;
    	build(rt<<1,l,m);
    	build(rt<<1|1,m+1,r);
    }
    
    void PushDown(int rt,int m){
    	if(cover[rt]!=-1){
    		cover[rt<<1]=cover[rt<<1|1]=cover[rt];
    		lsum[rt<<1]=rsum[rt<<1]=msum[rt<<1]=cover[rt]?0:(m-(m>>1));
    		lsum[rt<<1|1]=rsum[rt<<1|1]=msum[rt<<1|1]=cover[rt]?0:(m>>1);
    		cover[rt]=-1;
    	}
    }
    
    void PushUp(int rt,int m){
    	lsum[rt]=lsum[rt<<1];
    	rsum[rt]=rsum[rt<<1|1];
    	if(lsum[rt]==(m-(m>>1))) lsum[rt]+=lsum[rt<<1|1];
    	if(rsum[rt]==(m>>1)) rsum[rt]+=rsum[rt<<1];
    	msum[rt]=max(lsum[rt<<1|1]+rsum[rt<<1],max(msum[rt<<1],msum[rt<<1|1]));
    	msum[rt]=max(msum[rt],lsum[rt]);
    	msum[rt]=max(msum[rt],rsum[rt]);
    }
    
    int query(int rt,int l,int r,int w){
    	if(l==r) return l;
    	PushDown(rt,r-l+1);
    	int m=(l+r)>>1;
    	if(msum[rt<<1]>=w) return query(rt<<1,l,m,w);
    	else if(rsum[rt<<1]+lsum[rt<<1|1]>=w) return m-rsum[rt<<1]+1;
    	return query(rt<<1|1,m+1,r,w); 
    }
    
    void update(int rt,int L,int R,int l,int r,int c){
    	if(L<=l&&r<=R){
    		cover[rt]=c;
    		lsum[rt]=rsum[rt]=msum[rt]=c?0:r-l+1;
    		return ;
    	}
    	PushDown(rt,r-l+1);
    	int m=(l+r)>>1;
    	if(L<=m) update(rt<<1,L,R,l,m,c);
    	if(m<R) update(rt<<1|1,L,R,m+1,r,c);
    	PushUp(rt,r-l+1);
    }
    
    int main(){
    	int n,m,op,a,b;
    	while(scanf("%d%d",&n,&m)!=EOF){
    		build(1,1,n);
    		for(int i=1;i<=m;i++){
    			scanf("%d",&op);
    			if(op==1){
    				scanf("%d",&a);
    				if(msum[1]>=a){
    					int p=query(1,1,n,a);
    					update(1,p,p+a-1,1,n,1);
    					printf("%d
    ",p);
    				}
    				else printf("0
    ");
    			}
    			else{
    				scanf("%d%d",&a,&b);
    				update(1,a,a+b-1,1,n,0);
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    7月的尾巴,你是XXX
    戏说Android view 工作流程《下》
    “燕子”
    Android开机动画bootanimation.zip
    戏说Android view 工作流程《上》
    ViewController里已连接的IBOutlet为什么会是nil
    My first App "Encrypt Wheel" is Ready to Download!
    iOS开发中角色Role所产生的悲剧(未完)
    UIScrollView实现不全屏分页的小技巧
    Apple misunderstood my app,now my app status changed to “In Review”
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4320097.html
Copyright © 2011-2022 走看看