【[HNOI2004]宠物收养场】平衡树板题

这可是trajan发明的spaly!

传送门:  https://www.luogu.org/problemnew/show/P2286

平衡树板题?因为实际上同时只有一个树存在,所以只需要建一颗树就好,做个标记是宠物树还是人类树。每次求个前驱后继就可以了。。(之前后继写错了居然还有80分,贼水的数据,搞得这么大的错误我都不知道。。。)

好像做完后看了下别人的做法,直接setSTL搞定?%%%,不过我想2004年应该享受不了STL大法吧,,,

当作我的平衡树的学习开始,fighting!。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define maxn 200005
const long long mod=1000000;
using namespace std;
long long n,bj=233,ans;
long long root,ls[maxn+300],rs[maxn+300],fa[maxn+300],dat[maxn+300],tot,siz[maxn+300];
inline void zigzag(long long x,long long knd)
{
	long long y=fa[x],z=fa[y];
	if(ls[z]==y) ls[z]=x;
	else rs[z]=x;
	fa[x]=z; fa[y]=x;
	if(knd==1)
	{
		ls[y]=rs[x];
		fa[ls[y]]=y;
		rs[x]=y;
	}
	else
	{
		rs[y]=ls[x];
		fa[rs[y]]=y;
		ls[x]=y;
	}
	siz[x]=siz[y];
	siz[y]=siz[ls[y]]+siz[rs[y]]+1;
}
inline void zig(long long x) { zigzag(x,1); }
inline void zag(long long x) { zigzag(x,2); }
void splay(long long x)
{
	long long y,z;
	while(fa[x])
	{
		y=fa[x]; z=fa[y];
		if(z)
		{
			if(ls[z]==y)
			{
				if(ls[y]==x) { zig(y); zig(x); }
				else { zag(x); zig(x); }
			}
			else
			{
				if(rs[y]==x) { zag(y); zag(x); }
				else { zig(x); zag(x); }
			}
		}
		else
		{
			if(ls[y]==x) zig(x);
			else zag(x);
		}
	}
	root=x;
}
long long getmax(long long x)
{
	while(rs[x]) x=rs[x];
	return x;
}
long long getmin(long long x)
{
	while(ls[x]) x=ls[x];
	return x;
}
void ins(long long k)
{
	if(!tot) { dat[++tot]=k; siz[tot]=1; fa[tot]=ls[tot]=rs[tot]=0; root=tot; return; }
	++tot; 
	long long p=root;
	while(p)
	{
		siz[p]++;
		if(k<dat[p]) 
		{
			if(ls[p]) p=ls[p];
			else { ls[p]=tot; break; }
		}
		else
		{
			if(rs[p]) p=rs[p];
			else { rs[p]=tot; break; } 
		}
	}
	siz[tot]=1; dat[tot]=k; fa[tot]=p; ls[tot]=rs[tot]=0; splay(tot);
}
void del(long long p)
{
	splay(p);
	long long ll=ls[p],rr=rs[p];
	fa[ll]=fa[rr]=ls[p]=rs[p]=0;
	if(!ll)
	{
		root=rr; return;
	}
	ll=getmax(ll);
	splay(ll);
	fa[ll]=0; fa[rr]=ll;
	rs[ll]=rr;
	siz[root]+=siz[rs[root]];
	return;
}
int fid(int x)
{
	int p=root;
	while(p)
	{
		if(dat[p]==x) break;
		else if(dat[p]<x) p=rs[p];
		else p=ls[p];
	}
	return p;	
}
int main()
{
	scanf("%lld",&n);
	long long a,b,bjl,bjr;
	for(long long i=1;i<=n;i++)
	{
		scanf("%lld%lld",&a,&b);
		if(siz[root]==0)
		{
			bj=a;
			ins(b);
		}
		else if(bj==a) ins(b); 
		else 
		{
			int aha=fid(b);
			if(aha)
			{
				del(aha);
				continue;
			}
			ins(b);
			if(ls[root])bjl=getmax(ls[root]); if(rs[root])bjr=getmin(rs[root]);
			if(!ls[root])
			{
				ans=(ans+abs(dat[bjr]-b))%mod;
				del(bjr); del(tot);
			}
			else if(!rs[root])
			{
				ans=(ans+abs(dat[bjl]-b))%mod;
				del(bjl); del(tot);
			}
			else if(abs(dat[bjl]-b)<=abs(dat[bjr]-b))
			{
				ans=(ans+abs(dat[bjl]-b))%mod;
				del(bjl); del(tot);
			}
			else 
			{
				ans=(ans+abs(dat[bjr]-b)%mod)%mod;
				del(bjr); del(tot);
			}
		}
	}
	printf("%lld",ans);
}

 

posted @ 2018-03-30 00:10  Newuser233  阅读(44)  评论(0)    收藏  举报