您的位置:首页 > 其它

BZOJ 1208 [HNOI2004]宠物收养所 | SPlay模板题

2017-12-26 15:59 489 查看

题目:

洛谷也能评

题解:

记录一下当前树维护是宠物还是人,用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
,fa
,ls
,rs
,sze
,cnt
,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;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: