BZOJ1208&&洛谷P2286 [HNOI2004]宠物收养场

Splay半模板题

//By AcerMo
//SPLAY毒瘤的加点分割线 
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lli long long int
using namespace std;
//*-----------------------头文件--------------------------------*\/
const int M=200050;
const int mod=1e6;
struct Splay
{
	int so[2],val,fa;
}t[M];
int rt,n,tot;
//*-----------------------变量定义------------------------------*\/
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
//*--------------------------快读-------------------------------*\/
inline void zigzag(int x)
{
	int y=t[x].fa;
	int z=t[y].fa;
	int k=(x==t[y].so[1]);
	t[z].so[y==t[z].so[1]]=x;
	t[x].fa=z;
	t[y].so[k]=t[x].so[k^1];
	t[t[x].so[k^1]].fa=y;
	t[x].so[k^1]=y;
	t[y].fa=x;
	return ;
}
//*----------------旋转,交换父节点及子节点---------------------*\/ 
inline void splay(int x,int goal)
{
	while (t[x].fa!=goal)
	{
		int y=t[x].fa;
		int z=t[y].fa;
		if (z!=goal)
			(t[z].so[0]==y)^(t[y].so[0]==x)?zigzag(x):zigzag(y);
		zigzag(x);
	}
	return (void)(goal==0?rt=x:rt=rt);
} 
//*---------------------没事就转一转----------------------------*\/
inline void insert(int x)
{
	int u=rt,fa=0;
	while (u&&t[u].val!=x)
		fa=u,u=t[u].so[t[u].val<x];	
	if (!u)
	{
		u=++tot;
		if (fa) t[fa].so[t[fa].val<x]=u;
		t[u].fa=fa;t[u].so[0]=t[u].so[1]=0;
		t[u].val=x; 
	}
	return (void)(splay(u,0));
}
//*------------------------加个点-------------------------------*\/ 
inline void find(int x)
{
	int u=rt;if (!u) return ;
	while (t[u].so[x>t[u].val]&&x!=t[u].val) u=t[u].so[x>t[u].val];
 	return (void)(splay(u,0));
}
inline int nxt(int x,int fa)
{
	find(x);int u=rt;
	if (t[u].val>=x&&fa) return u;
	if (t[u].val<=x&&!fa) return u;
	u=t[u].so[fa];
	while (t[u].so[fa^1]) u=t[u].so[fa^1];
	return u;
}
//*------------------------get前驱and后继-----------------------*\/ 
inline int nxts(int x,int fa)
{
	find(x);int u=rt;
	if (t[u].val>x&&fa) return u;
	if (t[u].val<x&&!fa) return u;
	u=t[u].so[fa];
	while (t[u].so[fa^1]) u=t[u].so[fa^1];
	return u;
}
inline void del(int x)
{
	int ls=nxts(x,0),rs=nxts(x,1);
	splay(ls,0);splay(rs,ls);
	return (void)(t[rs].so[0]=0);	
}
//-------------------------理所当然的删除-----------------------*\/ 
int main()
{
	n=read();int cnt=0,ans=0;
	insert(214748364);insert(-214748364);
	for (int i=1;i<=n;i++)
	{
		int k=read(),x=read();
		if (cnt==0) insert(x);
		else if (cnt>0)
		{
			if (k==0) insert(x);
			else 
			{
				int fir=t[nxt(x,0)].val;//前驱
				int sec=t[nxt(x,1)].val;//后继
				if (abs(fir-x)<=abs(sec-x))
					ans+=abs(fir-x),ans%=mod,del(fir);
				else ans+=abs(sec-x),ans%=mod,del(sec);
			}
		}
		else 
		{
			if (k==1) insert(x);
			else 
			{
				int fir=t[nxt(x,0)].val;
				int sec=t[nxt(x,1)].val;
				if (abs(fir-x)<=abs(sec-x))
					ans+=abs(fir-x),ans%=mod,del(fir);
				else ans+=abs(sec-x),ans%=mod,del(sec);
			}
		}
		cnt+=(k==0?1:-1);
	}
	return cout<<ans,0;
}
//*--------------------------主函数-----------------------------*\/ 

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/81158730
今日推荐