BZOJ 1208 [HNOI2004]宠物收养所 | SPlay模板题
题目:
题解:
记录一下当前树维护是宠物还是人,用Splay维护插入和删除.
对于任何一次询问操作都求一下value的前驱和后继(这里前驱和后继是可以和value相等的),比较哪个差值绝对值小就好啦
#include<cstdio> #include<algorithm> #include<cstring> #define N 800010 #define MOD 1000000 #define which(x) (ls[fa[(x)]]==(x)) typedef long long ll; using namespace std; int n,root,tot,val[N],fa[N],ls[N],rs[N],sze[N],cnt[N],flag,op,value; ll ans; int read() { int ret=0,neg=1; char j=getchar(); for (;j>'9' || j<'0';j=getchar()) if (j=='-') neg=-1; for (;j>='0' && j<='9';j=getchar()) ret=ret*10+j-'0'; return ret*neg; } void Upt(int x) {sze[x]=sze[ls[x]]+sze[rs[x]]+1;} void Rotate(int u) { int v=fa[u],w=fa[v],b=which(u)?rs[u]:ls[u]; if (w) which(v)?ls[w]=u:rs[w]=u; which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v); fa[u]=w,fa[v]=u; if (b) fa[b]=v; Upt(v),Upt(u); } void Splay(int x) { while (fa[x]) { if (fa[fa[x]]) if (which(x)==which(fa[x])) Rotate(fa[x]); else Rotate(x); Rotate(x); } root=x; } void Insert(int x) { int cur=root,v=0; while (cur) if (x<val[v=cur]) cur=ls[cur]; else cur=rs[cur]; fa[++tot]=v,val[tot]=x,sze[tot]=1; if (v) x<val[v]?ls[v]=tot:rs[v]=tot; Splay(tot); } int Find(int x) { int cur=root,v=0; while (cur && val[cur]!=x) if (x<val[v=cur]) cur=ls[cur]; else cur=rs[cur]; return cur?cur:v; } int getmin(int x) { while (ls[x]) x=ls[x]; return x; } int getmax(int x) { while (rs[x]) x=rs[x]; return x; } int getpre(int x) { int u=Find(x); Splay(u); if (val[u]<=x) return u; return getmax(ls[u]); } int getnxt(int x) { int u=Find(x); Splay(u); if (val[u]>=x) return u; return getmin(rs[u]); } void Erase(int x) { Splay(x); if (ls[x]==0 && rs[x]==0) root=0; else if (ls[x]==0 || rs[x]==0) root=ls[x]+rs[x],fa[root]=0; else{ fa[ls[x]]=0; int v=getmax(ls[x]); Splay(v); rs[v]=rs[x],fa[rs[x]]=v,Upt(root); } } int main() { n=read(); for (int i=1;i<=n;i++) { op=read(),value=read(); if (sze[root]==0) Insert(value),flag=op; else if (op!=flag) { int u=getpre(value),v=getnxt(value); if (u!=0 && (v==0 || value-val[u]<=val[v]-value)) ans=(ans+value-val[u])%MOD,Erase(u); else ans=(ans+val[v]-value)%MOD,Erase(v); } else Insert(value); } printf("%lld",ans); return 0; }