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;
    }
    

      

  • 相关阅读:
    NSClassFromString,NSSelectorFromString,isKingOfClass
    [ios2]10大iOS开发者最喜爱的类库
    [ios2]iphone编程中使用封装的NSLog来打印调试信息 【转】
    [ios2]蓝牙通信【转】
    [ios] Xcode使用设置相关-快捷键【转】
    iOS图片设置圆角
    iOS 时间戳转时间
    iOS 时间转时间戳
    iOS loading等待图
    iOS简便写法
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4320097.html
Copyright © 2011-2022 走看看