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