zoukankan      html  css  js  c++  java
  • 线段树——区间合并 区间更新 模板

    线段树 区间合并模板  --区间更新

    题目:http://poj.org/problem?id=3667 

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>          //区间合并 区间更新 
    using namespace std;
    
    struct node{
    	int ls,rs,ms;
    };
    node tree[4*80000];
    int lazy[4*80000];
    void pushup(int cr,int l,int r){   
    	tree[cr].ls=tree[cr<<1].ls;   //左端点最长连续 
    	tree[cr].rs=tree[cr<<1|1].rs; //右端点最长连续 
    	tree[cr].ms=max( tree[cr<<1].rs+tree[cr<<1|1].ls,max( tree[cr<<1].ms,tree[cr<<1|1].ms) ); //区间最长连续 
    	int mid=(l+r)/2;
    	if(tree[cr<<1].ls==mid-l+1) tree[cr].ls+=tree[cr<<1|1].ls;
    	if(tree[cr<<1|1].rs==r-mid) tree[cr].rs+=tree[cr<<1].rs;
    }	
    void pushdown(int l,int r,int cr){  //lazy[cr]=1 表示空出房间,lazy[cr]=0 表示入驻房间 
    	if(lazy[cr]!=-1){
    		int mid=(l+r)/2;
    		lazy[cr<<1]=lazy[cr];
    		lazy[cr<<1|1]=lazy[cr];
    		tree[cr<<1].rs=tree[cr<<1].ls=tree[cr<<1].ms=lazy[cr]*(mid-l+1);
    		tree[cr<<1|1].ls=tree[cr<<1|1].ms=tree[cr<<1|1].rs=lazy[cr]*(r-mid);
    
    		lazy[cr]=-1;
    	}
    }
    void build(int l,int r,int cr){
    	if(l==r){
    		tree[cr].ls=tree[cr].rs=tree[cr].ms=1;
    		return ;
    	}
    	int mid=(l+r)/2;
    	build(l,mid,cr<<1);
    	build(mid+1,r,cr<<1|1);
    	pushup(cr,l,r);
    }
    void update(int l,int r,int cr,int L,int R,int val){    
    	if(L==l&&R==r){
    		tree[cr].ls=tree[cr].rs=tree[cr].ms=(r-l+1)*val;
    		lazy[cr]=val;
    		return ;
    	}
    	int mid=(L+R)/2;
    	pushdown(L,R,cr);
    	if(l<=mid) update( l,min(r,mid),cr<<1,L,mid,val );
    	if(r>mid) update( max(mid+1,l),r,cr<<1|1,mid+1,R,val);
    	pushup(cr,L,R);
    }
    int query(int L,int R,int cr,int n){ ///找到区间的左端点 
    	if(L==R){
    		return L;
    	}
    	int mid=(L+R)/2;
    	pushdown(L,R,cr);
    	if(tree[cr<<1].ms>=n){  //左 
    		return query(L,mid,cr<<1,n);
    	}
    	if(tree[cr<<1|1].ls+tree[cr<<1].rs>=n){	//中 
    		return mid-tree[cr<<1].rs+1;
    	}
    	if(tree[cr<<1|1].ms>=n){
    		return query(mid+1,R,cr<<1|1,n);
    	}
    	return 0;
    }
    int main(){
    	int n,m;
    	while(EOF!=scanf("%d%d",&n,&m)){
    		memset(lazy,-1,sizeof(lazy));
    		build(1,n,1);
    		for(int j=1;j<=m;j++){
    			int a;
    			scanf("%d",&a);
    			if(a==1){
    				int b;
    				scanf("%d",&b);
    				int pp=query(1,n,1,b);
    				if(pp) {
    					update(pp,pp+b-1,1,1,n,0);
    				}
    				printf("%d
    ",pp);	
    			}
    			else{
    				int b,c;
    				scanf("%d%d",&b,&c);
    				update(b,b+c-1,1,1,n,1);
    			}		
    		}
    	}
    }
    

      

  • 相关阅读:
    多态
    没有抽象方法的抽象类有什么意义
    抽象类继承(雇员练习)
    怎样在win7中 安装Tomcat7.0
    继承训练
    Java的接口和抽象类
    jQuery插件的学习
    jQuery学习之路-A
    android之路-android事件处理-OnTouchListener
    丢弃的东西,还能否找回?
  • 原文地址:https://www.cnblogs.com/z-bear/p/9431983.html
Copyright © 2011-2022 走看看