zoukankan      html  css  js  c++  java
  • gym 101480 Problem C: Cow Confinement 题解

    gym 101480 Problem C: Cow Confinement 题解

    算法知识:dp+扫描线。

    从下往上扫描,维护一个线段树就可以了。线段树支持区间清零,区间加和单点查询。

    Warning:扫描线预处理排序的部分需要注意先后顺序。

    /*
    {
    ######################
    #       Author       #
    #        Gary        #
    #        2020        #
    ######################
    */
    #include<bits/stdc++.h>
    #define rb(a,b,c) for(int a=b;a<=c;++a)
    #define rl(a,b,c) for(int a=b;a>=c;--a)
    #define LL long long
    #define IT iterator
    #define PB push_back
    #define II(a,b) make_pair(a,b)
    #define FIR first
    #define SEC second
    #define FREO freopen("check.out","w",stdout)
    #define rep(a,b) for(int a=0;a<b;++a)
    #define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
    #define random(a) rng()%a
    #define ALL(a) a.begin(),a.end()
    #define POB pop_back
    #define ff fflush(stdout)
    #define fastio ios::sync_with_stdio(false)
    #define check_min(a,b) a=min(a,b)
    #define check_max(a,b) a=max(a,b)
    using namespace std;
    //inline int read(){
    //    int x=0;
    //    char ch=getchar();
    //    while(ch<'0'||ch>'9'){
    //        ch=getchar();
    //    }
    //    while(ch>='0'&&ch<='9'){
    //        x=(x<<1)+(x<<3)+(ch^48);
    //        ch=getchar();
    //    }
    //    return x;
    //}
    const int INF=0x3f3f3f3f;
    typedef pair<int,int> mp;
    /*}
    */
    const int N=1<<20;
    bool asi[N+N];//是否都设置成0
    int delta[N+N];//增量
    void pd(int now){
    	if(asi[now]){
    		asi[now<<1]=asi[now<<1|1]=1;
    		delta[now<<1]=delta[now<<1|1]=delta[now];
    	}
    	else{
    		delta[now<<1]+=delta[now];
    		delta[now<<1|1]+=delta[now];
    	}
    	asi[now]=0;
    	delta[now]=0;
    }
    void Assign(int a,int b,int now=1,int l=1,int r=N+1){
    	if(r<=a||l>=b){
    		return;
    	}
    	if(r<=b&&l>=a){
    		delta[now]=0;
    		asi[now]=1;
    		return ;
    	}
    	pd(now);
    	int mid=(l+r)>>1;
    	Assign(a,b,now<<1,l,mid);
    	Assign(a,b,now<<1|1,mid,r);
    }
    void Add(int a,int b,int val,int now=1,int l=1,int r=N+1){
    	if(r<=a||l>=b) return ;
    	if(r<=b&&l>=a){
    		delta[now]+=val;
    		return;
    	}
    	pd(now);
    	int mid=(l+r)>>1;
    	Add(a,b,val,now<<1,l,mid);
    	Add(a,b,val,now<<1|1,mid,r);
    }
    int query(int pos){
    	pos+=N-1;
    	int rest=0;
    	while(pos){
    		if(asi[pos]){
    			rest=0;
    		}	
    		rest+=delta[pos];
    		pos>>=1;
    	}
    	return rest;
    }
    int answer[N],tmpanswer[N]/*记录每一个fence右下角的答案*/;
    int f,m,n;
    set<int> wall;
    struct Event{
    	int ty;//种类
    	/*
    	1. 上边界 
    	2. 下边界
    	3. 花 
    	4. 牛 
    	*/ 
    	int r,c,len,id;
    	Event(){}
    	Event(int T,int X,int Y){
    		ty=T;
    		r=X;
    		c=Y;
    	} 
    	Event(int T,int X,int Y,int L,int I){
    		ty=T;
    		r=X;
    		c=Y;
    		len=L;
    		id=I;
    	} 
    	bool operator < (Event oth){
    		if(r!=oth.r) return r>oth.r;
    		if((!(ty<=2&&oth.ty<=2))&&ty!=oth.ty) return ty<oth.ty;
    		return c<oth.c;
    	}
    };
    vector<Event> v;
    int main(){
    	scanf("%d",&f);
    	rb(i,1,f){
    		int r1,c1,r2,c2;
    		scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
    		r1--;
    		v.PB(Event(1,r1,c1,c2-c1+1,i));
    		v.PB(Event(2,r2,c1,c2-c1+1,i));
    	}
    	scanf("%d",&m);
    	rb(i,1,m){
    		int r,c;
    		scanf("%d%d",&r,&c);
    		v.PB(Event(3,r,c));
    	}
    	scanf("%d",&n); 
    	rb(i,1,n){
    		int r,c;
    		scanf("%d%d",&r,&c);
    		v.PB(Event(4,r,c,0,i));
    	}
    	sort(ALL(v));
    	for(int i=0;i<v.size();++i){
    		int j;
    		for(j=i;j<v.size()&&v[j].r==v[i].r;++j){
    			Event Eve=v[j];
    			if(Eve.ty==1){
    				Assign(Eve.c,Eve.c+Eve.len);
    				wall.erase(Eve.c-1);
    				wall.erase(Eve.c+Eve.len-1);
    				int tmp=query(Eve.c+Eve.len);
    				tmp-=tmpanswer[Eve.id];
    				auto can=wall.lower_bound(Eve.c);
    				if(can==wall.begin()) Add(1,Eve.c+Eve.len,tmp);
    				else{
    					--can;
    					Add((*can)+1,Eve.c+Eve.len,tmp);
    				}
    				Add(Eve.c,Eve.c+Eve.len,tmpanswer[Eve.id]);
    			}
    			if(Eve.ty==2){
    				wall.insert(Eve.c-1);
    				wall.insert(Eve.c+Eve.len-1);
    				Assign(Eve.c,Eve.c+Eve.len);
    				tmpanswer[Eve.id]=query(Eve.c+Eve.len);
    			}
    			if(Eve.ty==3){
    				auto can=wall.lower_bound(Eve.c);
    				if(can==wall.begin()) Add(1,Eve.c+1,1);
    				else{
    					--can;
    					Add((*can)+1,Eve.c+1,1);
    				}
    			}
    			if(Eve.ty==4){
    				answer[Eve.id]=query(Eve.c);
    			}
    		}
    		i=j-1;
    	}
    	rb(i,1,n) printf("%d
    ",answer[i]);
    	return 0;
    }/*
    
    4
    2 2 8 4
    1 9 4 10
    6 7 9 9
    3 3 7 3
    
    1
    2 2 8 4
    9
    3 4
    8 4
    11 5
    10 7
    10 8
    9 8
    2 8
    4 11
    9 11
    1
    1 1
    
    */
    
  • 相关阅读:
    管理表空间和数据文件——维护表空间——改变表空间的读写状态和改变表空间名称
    管理表空间和数据文件——数据库逻辑结构
    管理用户和PROFILE ——管理PROFILE——使用PROFILE管理口令
    管理对象空间——管理存储参数
    管理表空间和数据文件——显示表空间和数据文件信息
    oracle Wallet的使用
    管理表空间和数据文件——维护表空间——设置默认表空间和删除表空间和删除数据文件盒临时文件
    管理用户和PROFILE——用户方案和profile
    管理表空间和数据文件——建立表空间——建立临时表空间
    启动和停止数据库——停顿和暂停数据库
  • 原文地址:https://www.cnblogs.com/gary-2005/p/14141595.html
Copyright © 2011-2022 走看看