传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1208
Splay查询前驱和后继
Code
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define N 80010
#define MOD 1000000
#define ls(x) tr[x].l
#define rs(x) tr[x].r
#define fa(x) tr[x].f
using namespace std;
typedef long long ll;
struct node
{
int l,r,v,size,f;
};
node tr[N];
int n,tot,root,t1,t2,sum1,sum2,maxn;
ll ans;
void PushUp(int x)
{
tr[x].size=tr[ls(x)].size+tr[rs(x)].size+1;
}
void zig(int x)
{
int y=fa(x);
int z=fa(y);
if(y==ls(z))ls(z)=x;
else rs(z)=x;
fa(rs(x))=y,ls(y)=rs(x),rs(x)=y,fa(y)=x,fa(x)=z;
PushUp(y),PushUp(x);
if(y==root)root=x;
}
void zag(int x)
{
int y=fa(x);
int z=fa(y);
if(y==ls(z))ls(z)=x;
else rs(z)=x;
fa(ls(x))=y,rs(y)=ls(x),ls(x)=y,fa(y)=x,fa(x)=z;
PushUp(y),PushUp(x);
if(y==root)root=x;
}
void splay(int &x,int d)
{
while(fa(x)!=d)
{
if(ls(fa(x))==x)zig(x);
else zag(x);
}
}
void insert(int x)
{
if(!root)
{
root=++tot;
tr[tot].v=x,tr[tot].size=1;
return ;
}
int p=root,z;
while(p)
{
z=p;
tr[p].size++;
if(x<tr[p].v)p=ls(p);
else p=rs(p);
}
if(x<tr[z].v)ls(z)=++tot;
else rs(z)=++tot;
tr[tot].v=x,tr[tot].size=1,fa(tot)=z;
splay(tot,0);
}
void query_before(int k,int x)
{
if(!k)return ;
if(x>=tr[k].v)
{
if(tr[t1].v<tr[k].v)t1=k;
query_before(rs(k),x);
}else query_before(ls(k),x);
}
void query_after(int k,int x)
{
if(!k)return ;
if(x<=tr[k].v)
{
if(tr[t2].v>tr[k].v)t2=k;
query_after(ls(k),x);
}else query_after(rs(k),x);
}
void del(int &k)
{
splay(k,0);
if(ls(k)*rs(k)==0)root=ls(k)+rs(k);
else{
int x=rs(k);
while(ls(x))x=ls(x);
ls(x)=ls(k),fa(ls(k))=x;
root=rs(k);
}
fa(root)=0;
}
ll doing(int opt,int x)
{
int t=0;
t1=0,t2=maxn;
query_before(root,x);
query_after(root,x);
if(t1==0)t=t2;
else if(t2==0x7fffffff)t=t1;
else{
if(x-tr[t1].v<=tr[t2].v-x)t=t1;
else t=t2;
}
del(t);
if(opt==0)sum2--;
else sum1--;
// printf("%d\n",tr[t].v);
return (ll)abs(x-tr[t].v);
}
int main()
{
// freopen("pet2.in","r",stdin);
// freopen("pet.out","w",stdout);
cin>>n;
maxn=n+1;
tr[maxn].v=0x7fffffff;
for(int i=1;i<=n;i++)
{
int opt,x;
scanf("%d%d",&opt,&x);
switch(opt)
{
case 0: if(!sum2)insert(x),sum1++;
else ans=(doing(0,x)+ans)%MOD;
break;
case 1: if(!sum1)insert(x),sum2++;
else ans=(doing(1,x)+ans)%MOD;
break;
}
}
cout<<ans<<endl;
return 0;
}