用Splay按照题意模拟即可
注意边界情况的特判 pre返回的是-INF!以及INF的取值!
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define ll long long
const int N=80005;
const int mod=1000000;
const int INF=2147483600;
using namespace std;
template<class T>
inline void read(T &x)
{
x=0; int f=1;
static char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
x*=f;
}
int n,k,cnt,root,tot;
struct Tree
{
int fa,lc,rc,size;
ll val;
}t[N];
inline int which(int u){return t[t[u].fa].rc==u;}
inline void pushup(int u){t[u].size=t[t[u].lc].size+t[t[u].rc].size+1;}
inline void Rotate(int u)
{
int v=t[u].fa,w=t[v].fa;
int b=(t[v].rc==u)?t[u].lc:t[u].rc;
t[v].fa=u; t[u].fa=w;
if(b) t[b].fa=v;
if(w) (t[w].lc==v?t[w].lc:t[w].rc)=u;
if(t[v].rc==u) t[u].lc=v,t[v].rc=b;
else t[u].rc=v,t[v].lc=b;
pushup(v); pushup(u);
}
inline void Splay(int u,int tar)
{
while(t[u].fa!=tar)
{
if(t[t[u].fa].fa!=tar)
{
if(which(u)==which(t[u].fa)) Rotate(t[u].fa);
else Rotate(u);
}
Rotate(u);
}
if(!tar) root=u;
}
inline void insert(ll val)
{
int u=root,v=0,dir;
while(u)
{
v=u;
if(val<t[u].val) dir=0,u=t[u].lc;
else dir=1,u=t[u].rc;
}
u=++tot;
t[u].fa=v; t[u].val=val; t[u].size=1;
if(v) (dir==0?t[v].lc:t[v].rc)=u;
Splay(u,0);
}
inline int find(ll val)
{
int u=root;
while(u)
{
if(val==t[u].val) break;
if(val<t[u].val) u=t[u].lc;
else u=t[u].rc;
}
if(u) Splay(u,0);
return u;
}
inline int findmax(int u)
{
while(t[u].rc) u=t[u].rc;
return u;
}
inline void Delete(ll val)
{
int u=find(val);
if(!t[u].lc||!t[u].rc)
{
root=t[u].lc+t[u].rc;
t[root].fa=0;
}
else
{
int v=findmax(t[root].lc);
Splay(v,u);
t[v].rc=t[u].rc; t[t[u].rc].fa=v; t[v].fa=0; root=v;
pushup(root);
}
}
inline ll pre(ll val)
{
int u=root,ans=0;
while(u)
{
if(val>t[u].val) ans=u,u=t[u].rc;
else u=t[u].lc;
}
return (ans==0?-INF:t[ans].val);
}
inline ll sub(ll val)
{
int u=root,ans=0;
while(u)
{
if(val<t[u].val) ans=u,u=t[u].lc;
else u=t[u].rc;
}
return (ans==0?INF:t[ans].val);
}
int main()
{
read(n);
ll ans=0;
int a; ll b;
for(int i=1;i<=n;i++)
{
read(a); read(b);
if(cnt==0)
{
insert(b);
k=a;
cnt++;
}
else if((k==a)) insert(b),cnt++;//同一类
else
{
ll last=pre(b),next=sub(b);
if(b-last==next-b)
{
Delete(last);
ans=(ans+b-last)%mod;
}
else
{
if(b-last<next-b) Delete(last),ans=(ans+b-last)%mod;
else Delete(next),ans=(ans+next-b)%mod;
}
cnt--;
}
}
cout<<ans<<endl;
return 0;
}
这篇博客主要介绍了如何使用Splay数据结构来解决HNOI2004比赛中关于宠物收养所的问题。内容涉及到Splay的特殊操作,包括删除节点的前驱和后继节点,并强调了处理边界条件的重要性,如返回值为-INF的情况以及INF的定义。
235

被折叠的 条评论
为什么被折叠?



