12827:千山鸟飞绝

# include <bits/stdc++.h>
# define 	N 		400010
# define 	ll 		long long
using namespace std;
int read(){
	int tmp=0, fh=1; char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
	while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
	return tmp*fh;
}
struct point{int x,y;}now;
struct node{int w,p;}p[N];
struct Tree{
	int pl,pr,tagi,tagj,fa;
	point num;
}T[N];
int ansi[N],ansj[N],rt[N],place,ti,size[N],n,m,at[N];
map <point, int> mp;
bool operator <(point x, point y){return x.x<y.x||x.x==y.x&&x.y<y.y;}
bool operator ==(point x, point y){return x.x==y.x&&x.y==y.y;}
void pushtag(int x){
	ansi[T[x].num.y]=max(ansi[T[x].num.y],T[x].tagi);
	ansj[T[x].num.y]=max(ansj[T[x].num.y],T[x].tagj);
	T[T[x].pl].tagi=max(T[T[x].pl].tagi,T[x].tagi);
	T[T[x].pl].tagj=max(T[T[x].pl].tagj,T[x].tagj);
	T[T[x].pr].tagi=max(T[T[x].pr].tagi,T[x].tagi);
	T[T[x].pr].tagj=max(T[T[x].pr].tagj,T[x].tagj);
	T[x].tagi=0; T[x].tagj=0;
}
void zig(int x){
	int y=T[x].fa;
	pushtag(y); pushtag(x);
	if (T[T[y].fa].pl==y) 
		T[T[y].fa].pl=x; else T[T[y].fa].pr=x;
	T[x].fa=T[y].fa;
	T[y].pl=T[x].pr; T[T[x].pr].fa=y;
	T[x].pr=y; T[y].fa=x;
}
void zag(int x){
	int y=T[x].fa;
	pushtag(y); pushtag(x);
	if (T[T[y].fa].pl==y) 
		T[T[y].fa].pl=x; else T[T[y].fa].pr=x;
	T[x].fa=T[y].fa;
	T[y].pr=T[x].pl; T[T[x].pl].fa=y;
	T[x].pl=y; T[y].fa=x;
}
void splay(int p, int x){
	int root=rt[p];
	if (x==root) return;
	while (T[x].fa!=root){
		int y=T[x].fa;
		if (T[y].fa==root)
			if (T[y].pl==x) zig(x); else zag(x);
		else if (T[T[y].fa].pl==y)
			if (T[y].pl==x) zig(y), zig(x);
				else zag(x), zig(x);
			else if (T[y].pl==x) zig(x), zag(x);
				else zag(y), zag(x);	
	}
	if (T[root].pl==x) zig(x); else zag(x);
	rt[p]=x;
}
void extend(int p, point x){
	int now=++place;
	at[x.y]=now;
	T[now].num=x;
	size[p]++;
	if (size[p]==1){
		rt[p]=now;
		return;
	}
	T[rt[p]].tagi=max(T[rt[p]].tagi,size[p]-1);	
	int i=rt[p],las=0; point mx;
	while (i!=0){
		mx=T[i].num;
		i=T[i].pr;
	}
	ansj[x.y]=max(ansj[x.y],mx.x);
	ansi[x.y]=max(ansi[x.y],size[p]-1);
	T[rt[p]].tagj=max(T[rt[p]].tagj,x.x);
	las=0, i=rt[p];
	while (i!=0){
		pushtag(i); las=i;
		if (T[i].num<x) i=T[i].pr; else i=T[i].pl;
	}
	if (T[las].num<T[now].num)
		T[las].pr=now; else T[las].pl=now;
	T[now].fa=las;
	splay(p,now);
}
void del(int p, point x){
	int i=rt[p];
	while (i!=0){
		pushtag(i); 
		if (T[i].num==x) break;
		if (T[i].num<x) i=T[i].pr; else i=T[i].pl;
	}
	splay(p,i);
	int l=T[rt[p]].pl,r=T[rt[p]].pr;
	T[l].fa=0; T[r].fa=0;
	if (l==0&&r==0) rt[p]=0;
		else if (l==0) rt[p]=r;
			else if (r==0) rt[p]=l;
				else {
					rt[p]=l;
					int las=0;
					while (l!=0){
						pushtag(l); las=l;
						l=T[l].pr;
					}
					splay(p,las);
					T[rt[p]].pr=r;
					T[r].fa=rt[p];
				}
	size[p]--;
}
int main(){
	n=read();
	for (int i=1; i<=n; i++){
		p[i].w=read(), now.x=read(), now.y=read();
		if (mp.find(now)==mp.end()) mp[now]=++ti;
		p[i].p=mp[now];
		extend(p[i].p,(point){p[i].w,i});
	}
	m=read();
	for (int i=1; i<=m; i++){
		int j=read(); now.x=read(),	now.y=read(); 
		if (mp.find(now)==mp.end()) mp[now]=++ti;
		int nex=mp[now];
		del(p[j].p,(point){p[j].w,j});
		extend(nex,(point){p[j].w,j});
		p[j].p=nex;
	}
	for (int i=1; i<=n; i++){
		splay(p[i].p,at[i]);
		pushtag(rt[p[i].p]);
		printf("%lld\n",(ll)ansi[i]*ansj[i]);
	}
	return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值