zoukankan      html  css  js  c++  java
  • joisc 2020 扫除

    算法1:
    考虑没有插入操作怎么办。
    先考虑sub3。
    定义一个点在边界上:它的右上角没有任何点。
    注意到无论怎么进行操作,在边界的点还是会在边界,且顺序不会交换。
    所以可以用线段树二分简单维护。
    再考虑sub4。
    sub4和sub3的区别:在sub3中每个点都在边界上,但是sub4并不。
    但是注意到如果一个点在边界上,则它在之后的操作它还是在边界上。
    所以可以使用线段树+平衡树维护。
    开平衡树维护边界上的点的x/y坐标。
    不能用线段树,因为要支持插入操作。
    在修改时在平衡树二分+平衡树区间赋值维护。
    在操作时,可能有新的点到达边界。
    使用两个线段树找点即可。
    (这个部分还是不太懂)
    由于每个点会被插入到平衡树中至多1次,所以时间复杂度是(O(nlog_2 n))
    有插入操作时,注意到每个修改操作对答案的贡献是独立的,于是可以使用时间线段树规避删除。
    算法2:
    算法1太难写了,考虑一种更好写的算法。
    考虑sub2,没有向上推的操作。
    一个点的y坐标不会变,维护个关于x坐标的线段树即可。
    拓展到sub4。
    直接拓展会有一个问题。
    一个操作相当于把区间([1,r])的点在线段树上坐标对(n-r)(max)
    然而操作的范围不一定是([1,n-r])
    比如我们要向上推。但是有一个比较小,但是距离特别长的向右推的操作把部分灰尘推走了。
    所以一个操作的是把区间([x,r])的点的坐标对(n-r)取max。
    我们要得到这个x。
    维护两个线段树,维护(x,y)轴的答案。
    按照顺序执行所有修改操作。
    对于一个修改操作, 把对应的区间对(len)取max。然后单点查询另一颗线段树在len位置的值。
    画图可以知道正确性。
    在查询操作时,由于一个推距离(=x)的点只能影响到某个坐标(<=x)的点,所以把所有点按照坐标从大到小排序然后分两维做。
    有插入操作时也可以时间线段树。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000010
    int n,m,q,x[N],y[N],ql[N],qr[N],ct,cc,le[N],tp[N],ax[N],ay[N],t[N];
    struct no{
    	int x,y;
    };
    vector<int>v[N*4];
    vector<no>op[2];
    int operator <(no x,no y){
    	return x.x>y.x||(x.x==y.x&&x.y>y.y);
    }
    int mx[N*40],cv,lc[N*40],rc[N*40],rt[2];
    void up(int &o,int l,int r,int x,int y,int z){
    	if(!o)
    		o=++cv;
    	if(r<x||y<l)
    		return;
    	if(x<=l&&r<=y){
    		mx[o]=max(mx[o],z);
    		return;
    	}
    	int md=(l+r)/2;
    	up(lc[o],l,md,x,y,z);
    	up(rc[o],md+1,r,x,y,z);
    }
    int qu(int o,int l,int r,int x){	
    	if(l==r)
    		return mx[o];
    	int md=(l+r)/2;
    	if(x<=md)
    		return max(qu(lc[o],l,md,x),mx[o]);
    	return max(qu(rc[o],md+1,r,x),mx[o]);
    }
    int cx(int x,int y){
    	return ax[x]>ax[y];
    }
    int cy(int x,int y){
    	return ay[x]>ay[y];
    }
    void ins(int o,int l,int r,int x,int y,int z){
    	if(r<x||y<l)
    		return;
    	if(x<=l&&r<=y){
    		v[o].push_back(z);
    		return;
    	}
    	int md=(l+r)/2;
    	ins(o*2,l,md,x,y,z);
    	ins(o*2+1,md+1,r,x,y,z);
    }
    void cl(){
    	for(int i=1;i<=cv;i++)
    		lc[i]=rc[i]=mx[i]=0;
    	rt[0]=rt[1]=cv=0;
    }
    void fz(int o,int l,int r){
    	op[0].clear();
    	op[1].clear();
    	cl();
    	for(int i=l;i<=r;i++){
    		int va=qu(rt[tp[i]^1],0,n,le[i]);
    		op[tp[i]].push_back((no){le[i],va});
    		up(rt[tp[i]],0,n,va,n-le[i]-1,le[i]+1);
    	}
    	cl();
    	sort(op[0].begin(),op[0].end());
    	sort(op[1].begin(),op[1].end());
    	sort(v[o].begin(),v[o].end(),cy);
    	int j=0;
    	for(int x:v[o]){
    		while(j<op[0].size()&&op[0][j].x>=ay[x]){
    			up(rt[0],0,n,op[0][j].y,n-op[0][j].x,n-op[0][j].x);
    			j++;
    		}
    		ax[x]=max(ax[x],qu(rt[0],0,n,ax[x]));
    	}
    	sort(v[o].begin(),v[o].end(),cx);
    	j=0;
    	for(int x:v[o]){
    		while(j<op[1].size()&&op[1][j].x>=ax[x]){
    			up(rt[1],0,n,op[1][j].y,n-op[1][j].x,n-op[1][j].x);
    			j++;
    		}
    		ay[x]=max(ay[x],qu(rt[1],0,n,ay[x]));
    	}
    	int md=(l+r)/2;
    	if(l>=r)return;
    	fz(o*2,l,md);
    	fz(o*2+1,md+1,r);
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&q);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&x[i],&y[i]);
    		t[i]=1;
    	}
    	for(int i=1;i<=q;i++){
    		int op;
    		scanf("%d",&op);
    		if(op==1){
    			int p;
    			scanf("%d",&p);
    			ax[++cc]=x[p];
    			ay[cc]=y[p];
    			qr[cc]=ct;
    			ql[cc]=t[p];
    		}
    		if(op==2){
    			int x;
    			scanf("%d",&x);
    			le[++ct]=x;
    			tp[ct]=0;
    		}
    		if(op==3){
    			int x;
    			scanf("%d",&x);
    			le[++ct]=x;
    			tp[ct]=1;
    		}
    		if(op==4){
    			int a,b;
    			scanf("%d%d",&a,&b);
    			x[++m]=a;
    			y[m]=b;
    			t[m]=ct+1;
    		}
    	}
    	for(int i=1;i<=cc;i++)
    		ins(1,1,ct,ql[i],qr[i],i);
    	fz(1,1,ct);
    	for(int i=1;i<=cc;i++)
    		printf("%d %d
    ",ax[i],ay[i]);
    }
    
  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/13858306.html
Copyright © 2011-2022 走看看