平衡树的简单应用,删除,求前驱和后继。
一般来说,会建两颗线段树,但事实上,题目可得,同一时间内,只会有宠物或人,所以,只要一颗就够了。
#include<bits/stdc++.h>
#define N 80000
#define mod 1000000
using namespace std;
int ch[N+1][2],siz[N+1],cnt[N+1],f[N+1],key[N+1],sz,rt;
int n,opt,x,ans,tmp1,tmp2,now,flag,num,mi,id;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
int x=0;
char c=nc();
while(c<'0'||c>'9')c=nc();
while(c<='9'&&c>='0')x=x*10+c-'0',c=nc();
return x;
}
inline void clear(int x)
{
ch[x][0]=ch[x][1]=f[x]=key[x]=cnt[x]=siz[x]=0;
}
inline int get(int x)
{
return ch[f[x]][1]==x;
}
inline void update(int x)
{
if(!x)return;
siz[x]=cnt[x];
if(!ch[x][0])siz[x]+=siz[ch[x][0]];
if(!ch[x][1])siz[x]+=siz[ch[x][1]];
}
inline void rotate(int x)
{
int old=f[x],oldf=f[old],which=get(x);
ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
f[old]=x,ch[x][which^1]=old;
f[x]=oldf;
if(oldf)ch[oldf][ch[oldf][1]==old]=x;
update(old),update(x);
}
inline void splay(int x)
{
for(int fa;fa=f[x];rotate(x))
if(f[fa])rotate(get(x)==get(fa)?fa:x);
rt=x;
}
inline void insert(int x)
{
if(rt==0){sz++,clear(sz),key[sz]=x,cnt[sz]=1,siz[sz]=1,rt=sz;return;}
int now=rt,fa=0;
while(true)
{
if(key[now]==x)
{
cnt[now]++;
update(now),update(fa);
splay(now);
return;
}
fa=now;
now=ch[now][key[now]<x];
if(now)continue;
sz++;clear(sz);
key[sz]=x,cnt[sz]=1,siz[sz]=1;
f[sz]=fa;ch[fa][key[fa]<x]=sz;
update(fa);
splay(sz);
return;
}
}
inline int pre()
{
int now=ch[rt][0];
while(ch[now][1])now=ch[now][1];
return now;
}
inline int suf()
{
int now=ch[rt][1];
while(ch[now][0])now=ch[now][0];
return now;
}
inline int find(int x)
{
int now=rt,ans=0;
while(true)
{
if(x<key[now])now=ch[now][0];
else
{
ans+=(ch[now][0]?siz[ch[now][0]]:0);
if(x==key[now]){splay(now);return ans+1;}
ans+=cnt[now];
now=ch[now][1];
}
}
}
inline int findx(int x)
{
int now=rt;
while(true)
{
if(ch[now][0]&&x<=siz[ch[now][0]])now=ch[now][0];
else
{
int tmp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now];
if(x<=tmp)return key[now];
x-=tmp,now=ch[now][1];
}
}
}
inline void del(int x)
{
int tmp=find(x);
if(cnt[rt]>1){cnt[rt]--,update(rt);return;}
if(!ch[rt][0]&&!ch[rt][1]){clear(rt),rt=0;return;}
if(!ch[rt][0])
{
int oldrt=rt;
rt=ch[rt][1],f[rt]=0;
clear(oldrt);
return;
}
if(!ch[rt][1])
{
int oldrt=rt;
rt=ch[rt][0],f[rt]=0;
clear(oldrt);
return;
}
int oldrt=rt,leftbig=pre();
splay(leftbig);
ch[rt][1]=ch[oldrt][1];
f[ch[oldrt][1]]=rt;
clear(oldrt);
return;
}
int main()
{
//freopen("in.txt","r",stdin);
n=read();
now=read(),x=read();
insert(x);num=1;
for(int i=2;i<=n;i++)
{
opt=read(),x=read();
if(opt!=now){
flag=true;
now=opt;
}
if(!flag)insert(x),num++;
else
{
if(num==0)
{
flag=false;
insert(x);
num++;
continue;
}
mi=~0u>>1;
insert(x);
tmp1=pre(),tmp2=suf();
if(tmp1&&abs(x-key[tmp1])<mi)mi=abs(x-key[tmp1]),id=tmp1;
if(tmp2&&abs(x-key[tmp2])<mi)mi=abs(x-key[tmp2]),id=tmp2;
ans=(ans+mi)%mod;
del(x);
del(key[id]);
num--;
}
}
cout<<ans;
return 0;
}