[HNOI2004]宠物收养场
# [[HNOI2004]宠物收养场 ](https://www.cnblogs.com/LeagueofLegends2004/articles/10312090.html )
[洛谷链接](https://www.luogu.org/problemnew/show/P2286)
这是一道比较简单的题目,一眼便可以看出来是一道很水的平衡树的题。想要解决此题首先就要至少会写一种平衡树,当然这道题用不到平衡树的所有操作,只有插入、删除、前驱、后继操作。由于作者太菜了只会使用常数巨大的splay,想必各位巨佬们一定用是红黑树之类的。
Solution
一种比较蠢的做法是开两棵splay(其实正解一个就够了),一棵用来存领养者的信息记为b,另一棵用来存宠物的信息记为a。当进来的进来的是宠物时,分两种情况。1.如果没有领养者,那么可以直接将宠物加入平衡树a中;2.如果有领养者,那么只要拿着这个宠物的特点值在平衡树b中去匹配一下(即找一下它的前驱和后继)。如果进来的是领养者就做相反的处理,然后就可以愉快地AC这道题了。时间复杂的是\(O(nlog_2n)\),对于80000的输入数据随便过。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define N 100005
#define mod 1000000
#define ll long long
#define rint register int
using namespace std;
inline char get(){ const int TOP=1000000;
static char T[TOP],*x=T,*y=T;
return x==y&&(y=(x=T)+fread(T,1,TOP,stdin),x==y)?EOF:*x++;
}
inline int read (){
register int num,sign=1;register char c;
while (((c=get())<'0'||c>'9')&&c!='-');c=='-'?num=sign=0:num=c-48;
while ((c=get())>='0'&&c<='9')num=(num<<3)+(num<<1)+(c-48);
return sign?num:-num;
}
class Tree{
public:
int root,len,S;
int f[N],r[N],l[N],data[N],cnt[N];
inline void rotate(rint x){
rint y=f[x],z=f[f[x]];
if(l[z]==y)l[z]=x;else r[z]=x;f[x]=z;
if(l[y]==x){l[y]=r[x];f[r[x]]=y;r[x]=y;f[y]=x;}else {r[y]=l[x];f[l[x]]=y;l[x]=y;f[y]=x;}
l[0]=r[0]=0;
}
inline void splay(rint x,rint rt){
for(;f[x]!=rt;rotate(x)){
rint y=f[x],z=f[f[x]];
if(z==rt)continue;
rotate((l[y]==x)^(l[z]==y)?x:y);
}
if(rt==0)root=x;
}
inline int find_pre(rint x){
rint u=root,res=-1;;
while(u){
if(data[u]<x&&(res==-1||data[u]>data[res]))res=u;
u=x<=data[u]?l[u]:r[u];
}
return res;
}
inline int find_sub(rint x){
rint u=root,res=-1;
while(u){
if(data[u]>x&&(res==-1||data[u]<data[res]))res=u;
u=x<data[u]?l[u]:r[u];
}
return res;
}
inline int find(rint x){
rint u=root,res=-1;
while(u&&data[u]!=x)u=x<data[u]?l[u]:r[u];
return u;
}
inline void insert(rint x){
rint u=root,fa=0;
while(u&&data[u]!=x){fa=u;u=x<data[u]?l[u]:r[u];}
if(u)cnt[u]++;
else{u=++len;
cnt[u]=1;data[u]=x;f[u]=fa;l[u]=r[u]=0;
if(x<data[fa])l[fa]=u;else r[fa]=u;
}
splay(u,0);S++;
}
inline void erase(rint x){
rint s=find_sub(x),p=find_pre(x);
splay(p,0);splay(s,p);
if(cnt[l[s]]>1){--cnt[l[s]];splay(l[s],0);return;}
l[s]=0;f[l[s]]=0;--S;
}
}a,b;
int n,x,y;
ll ans;
int main(){
n=read();
a.insert(2147483647);a.insert(-2147483647);
b.insert(2147483647);b.insert(-2147483647);
for(rint i=1;i<=n;++i){
x=read();y=read();
if(!x){
if(b.S>2){
if(!b.find(y)){
ll p=b.data[b.find_pre(y)],s=b.data[b.find_sub(y)];
if(abs(p-y)<abs(s-y))ans=(ans+abs(p-y))%mod,b.erase(p);
else ans=(ans+abs(s-y))%mod,b.erase(s);
}else a.erase(b.find(y));
}
else a.insert(y);
}else{
if(a.S>2){
if(!a.find(y)){
ll p=a.data[a.find_pre(y)],s=a.data[a.find_sub(y)];
if(abs(p-y)<=abs(s-y))ans=(ans+abs(p-y))%mod,a.erase(p);
else ans=(ans+s-y)%mod,a.erase(s);
}else a.erase(a.find(y));
}else b.insert(y);
}
}
printf("%d\n",ans);
}

浙公网安备 33010602011771号