【KD-tree】有理有据题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34454069/article/details/88054347

分析:

KD-tree+查询历史最大值
懒标记很多,有点麻烦。
代码里有注释

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 350010
using namespace std;
struct node{
	int x,y,Maxx,Maxy,Minx,Miny,id;
	node* l,*r,*fa;
	int Maxv;//Maxv ths max number of cover the whole section
	int ans;//The ans in this segment
	int now;//The number of cover the whole section now
	int pre;//The number of cover the whole section,and pushdown it to update subtree
	int sum;//The number of cover this segment now
	bool clr;
	void pushdown(){
		if(clr==0) pre=now;
		Maxv=max(Maxv,now);
		ans=max(ans,max(sum,Maxv));
		if(l!=NULL){
			l->Maxv=max(l->Maxv,Maxv);
			if(clr){
				if(l->clr==0)
					l->clr=1,l->pre=l->now+pre;
				l->Maxv=max(l->Maxv,l->now+pre);
				l->ans=max(l->ans,l->sum+pre);
				l->sum=l->now=now;
			}
			else
				l->now+=pre,l->sum+=pre;
		}
		if(r!=NULL){
			r->Maxv=max(r->Maxv,Maxv);
			if(clr){
				if(r->clr==0)
					r->clr=1,r->pre=r->now+pre;
				r->Maxv=max(r->Maxv,r->now+pre);
				r->ans=max(r->ans,r->sum+pre);
				r->sum=r->now=now;
			}
			else
				r->now+=pre,r->sum+=pre;
		}
		clr=0;
		now=pre=0;
	}
}t[MAXN],*rt;
bool cmpx(const node &a,const node &b){
	return a.x<b.x;
}
bool cmpy(const node &a,const node &b){
	return a.y<b.y;
}
node* build(int l,int r){
	int mid=(l+r)>>1;
	if(rand()%2==1)
		nth_element(t+l,t+mid,t+r+1,cmpx);
	else
		nth_element(t+l,t+mid,t+r+1,cmpy);
	swap(t[l],t[mid]);
	t[l].Maxx=t[l].Minx=t[l].x;
	t[l].Maxy=t[l].Miny=t[l].y;
	if(l!=mid){
		node *y=build(l+1,mid);
		y->fa=&t[l];
		t[l].l=y;
		t[l].Maxx=max(t[l].Maxx,y->Maxx);
		t[l].Maxy=max(t[l].Maxy,y->Maxy);
		t[l].Minx=min(t[l].Minx,y->Minx);
		t[l].Miny=min(t[l].Miny,y->Miny);
	}
	if(r!=mid){
		node *y=build(mid+1,r);
		y->fa=&t[l];
		t[l].r=y;
		t[l].Maxx=max(t[l].Maxx,y->Maxx);
		t[l].Maxy=max(t[l].Maxy,y->Maxy);
		t[l].Minx=min(t[l].Minx,y->Minx);
		t[l].Miny=min(t[l].Miny,y->Miny);
	}
	return t+l;
}
int L,R;
int pos[MAXN];
void calc(node *x){
	if(x->Minx>R||x->Maxy<L){
		if(x->clr==0) x->pre=x->now;
		x->Maxv=max(x->Maxv,x->now);
		x->ans=max(x->ans,x->sum);
		x->sum=x->now=0;
		x->clr=1;
		return ;	
	}
	if(x->Maxx<=R&&x->Miny>=L){
		x->sum++,x->now++;
		return ;
	}
	if(x->clr||x->pre||x->now) x->pushdown();
	if(x->x<=R&&x->y>=L){
		x->sum++;
		x->ans=max(x->ans,x->sum);	
	}
	else{
		x->ans=max(x->ans,x->sum);
		x->sum=0;	
	}
	if(x->l) calc(x->l);
	if(x->r) calc(x->r);
}
char S[20];
int main(){
	freopen("bomb.in","r",stdin);
	freopen("bomb.out","w",stdout);
	srand(0);
	int n,m,q,u;
	SF("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++){
		SF("%d%d",&t[i].x,&t[i].y);	
		t[i].id=i;
	}
	rt=build(1,n);
	for(int i=1;i<=n;i++)
		pos[t[i].id]=i;
	for(int i=1;i<=m;i++){
		SF("%d%d",&L,&R);
		calc(rt);	
	}
	for(int i=1;i<=q;i++){
		SF("%s",S);	
		if(S[0]=='A'){
			SF("%d%d",&L,&R);
			calc(rt);
		}
		if(S[0]=='C'){
			SF("%d",&u);
			u=pos[u];
			int ans=t[u].ans;
			int sum=t[u].sum;
			for(node *x=t[u].fa;x;x=x->fa){
				ans=max(ans,x->Maxv);
				if(x->clr){
					ans=max(ans,sum+x->pre);
					sum=0;
				}
				sum+=x->now;
			}
			ans=max(ans,sum);
			PF("%d\n",ans);
		}
		if(S[0]=='Q'){
			int ans=0;
			for(int i=1;i<=n;i++){
				if(t[i].pre||t[i].clr||t[i].now)
					t[i].pushdown();
				ans^=t[i].ans;
			}
			PF("%d\n",ans);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_34454069/article/details/88054347
今日推荐