【题解】 P2234 [HNOI2002]营业额统计

平衡树板题

原题传送门

这道题要用Splay,我博客里有对Splay的详细介绍

这道题目还算比较模板的

每输入一个数,先不要插入

要求一下前驱和后继与x差的最小值并加到答案中

再把x插入平衡树

然后你会发现过不了样例

发现相同的数字是会有的

所以还要写find函数,要多加一个变量来比最小:

find(x)!=0?0:inf;

剩下就没什么问题了qaq

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define root tree[0].ch[1]
#define inf 1000000005
using namespace std;
inline int read()
{
	register int x=0,f=1;register char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x*f;
}
inline int Min(register int a,register int b)
{
	return a<b?a:b;
}
struct Splay{
	int fa,ch[2],sum,rec,v;
}tree[32780];
int tot=0;
inline bool findd(register int x)
{
	return x==tree[tree[x].fa].ch[0]?0:1;
}
inline void connect(register int x,register int fa,register int son)
{
	tree[x].fa=fa;
	tree[fa].ch[son]=x;
}
inline void update(register int x)
{
	tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;
}
inline void rotate(register int x)
{
	int Y=tree[x].fa;
	int R=tree[Y].fa;
	int Yson=findd(x);
	int Rson=findd(Y);
	int B=tree[x].ch[Yson^1];
	connect(B,Y,Yson);
	connect(Y,x,Yson^1);
	connect(x,R,Rson);
	update(Y),update(x);
}
inline void splay(register int x,register int to)
{
	to=tree[to].fa;
	while(tree[x].fa!=to)
	{
		int y=tree[x].fa;
		if(tree[y].fa==to)
			rotate(x);
		else if(findd(x)==findd(y))
			rotate(y),rotate(x);
		else
			rotate(x),rotate(x);
	}
}
inline int newpoint(register int v,register int fa)
{
	tree[++tot].v=v;
	tree[tot].fa=fa;
	tree[tot].sum=tree[tot].rec=1;
	return tot;
}
inline void Insert(register int x)
{
	int now=root;
	if(root==0)	
	{
		newpoint(x,0);
		root=tot;
	}
	else
	{
		while(19260817)
		{
			++tree[now].sum;
			if(x==tree[now].v)
			{
				++tree[now].rec;
				splay(now,root);
				return;
			}
			int nxt=x<tree[now].v?0:1;
			if(!tree[now].ch[nxt])
			{
				int p=newpoint(x,now);
				tree[now].ch[nxt]=p;
				splay(p,root);
				return;
			}
			now=tree[now].ch[nxt];
		}
	}
}
inline int find(register int v)
{
	int now=root;
	while(19260817)
	{
		if(tree[now].v==v)
		{
			splay(now,root);
			return now;
		}
		int nxt=v<tree[now].v?0:1;
		if(!tree[now].ch[nxt])
			return 0;
		now=tree[now].ch[nxt];
	}
}
inline int lower(register int v)
{
	int now=root;
	int ans=-inf;
	while(now)
	{
		if(tree[now].v<v&&tree[now].v>ans)
			ans=tree[now].v;
		if(v>tree[now].v)
			now=tree[now].ch[1];
		else
			now=tree[now].ch[0];
	}
	return ans;
}
inline int upper(register int v)
{
	int now=root;
	int ans=inf;
	while(now)
	{
		if(tree[now].v>v&&tree[now].v<ans)
			ans=tree[now].v;
		if(v<tree[now].v)
			now=tree[now].ch[0];
		else
			now=tree[now].ch[1];
	}
	return ans;
}
int main()
{
	int n=read();
	int res=0;
	for(register int i=1;i<=n;++i)
	{
		int x=read();
		if(i==1)
			res=x;
		else
			res+=Min(Min(fabs(lower(x)-x),fabs(upper(x)-x)),find(x)!=0?0:inf);
		Insert(x);
	}
	printf("%d",res);
	return 0;
 } 
原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/9959886.html