Treap 解决。。
题目中可能会先来领养的人 或者 先来宠物,
根据那种先到,来决定以哪种作为 Treap 储存的信息,
之后我们构造一个 higher 函数 找到比 x 小的最近的,lower 函数找到比 x 大最近的,之后我们就进行比较选择最合适的,然后记录ans, del 那个点就好了。。。
以下是 AC 代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int mod = 1000000;
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
struct node
{
int rnd,v,w;
int l,r;
}tr[maxn];
#define ls tr[k].l
#define rs tr[k].r
int n,size,root,top,low,ans,now;
void lturn(int &k)
{
int t = tr[k].r;
tr[k].r = tr[t].l; tr[t].l = k;
k = t;
}
void rturn(int &k)
{
int t = tr[k].l;
tr[k].l = tr[t].r; tr[t].r = k;
k = t;
}
void insert(int &k,int x)
{
if(k == 0)
{
k = ++ size;
tr[k].l = tr[k].r = 0;
tr[k].v = x;
tr[k].rnd = rand();
return;
}
if(x > tr[k].v)
{
insert(rs, x);
if(tr[rs].rnd < tr[k].rnd) lturn(k);
}
else
{
insert(ls, x);
if(tr[ls].rnd < tr[k].rnd) rturn(k);
}
}
void del(int &k, int x)
{
if(k == 0) return;
if(tr[k].v == x)
{
if(ls * rs == 0) k = ls + rs;
else if(tr[ls].rnd < tr[rs].rnd)rturn(k),del(k, x);
else lturn(k),del(k, x);
}
else if(tr[k].v < x) del(rs, x);
else del(ls, x);
}
void lower(int k,int x)
{
if(k == 0) return;
if(tr[k].v <= x)
{
top = k; lower(rs, x);
}
else lower(ls, x);
}
void higher(int k,int x)
{
if(k == 0) return;
if(tr[k].v > x)
{
low = k; higher(ls, x);
}
else higher(rs, x);
}
int main()
{
n = read();
int num = 0;
int a,b;
for(int i=1;i<=n;i++)
{
a=read(), b=read();
if(!num){size=0;root=0,insert(root,b),now=a,num++;}//借鉴大犇思路,真的很好用
else if(a == now)
{
insert(root,b);
num++;
}
else
{
top=0; lower(root,b);
low=0; higher(root,b);
if(!low||(top&&tr[top].v&&b-tr[top].v<=tr[low].v-b))
{
ans=(ans+b-tr[top].v)%mod;
del(root,tr[top].v);
}
else
{
ans=(ans+tr[low].v-b)%mod;
del(root,tr[low].v);
}
num--;
}
}
printf("%d\n",ans);
return 0;
}