【[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);
}

浙公网安备 33010602011771号