[HNOI2004]宠物收养所

时间:2022-12-16 13:50:37

题目链接:戳我
其实也就是一个splay而已了。
但是一定要注意这种需要计算的,刚开始insert的时候插入极大值极小值的时候不要让它爆掉int.......(比如我刚开始就写了一个2147483647,一个-2147483647)
记录一个变量来表示当前是宠物剩余,还是领养者剩余。其他的没有什么了。
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
#define mod 1000000
using namespace std;
int n,m,root,cnt1,cnt2,tot,cnt;
long long ans;
struct Node{int ff,cnt,val,ch[2];}t[MAXN<<1];
inline void rotate(int x)
{
    int y=t[x].ff;
    int z=t[y].ff;
    int k=t[y].ch[1]==x;
    t[z].ch[t[z].ch[1]==y]=x; t[x].ff=z;
    t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].ff=y;
    t[x].ch[k^1]=y; t[y].ff=x;
}
inline void splay(int x,int goal)
{
    while(t[x].ff!=goal)
    {
        int y=t[x].ff;
        int z=t[y].ff;
        if(z!=goal)
            ((t[z].ch[0]==y)^(t[y].ch[0]==x))?rotate(x):rotate(y);
        rotate(x);
    }
    if(!goal) root=x;
}
inline void insert(int x)
{
    int u=root,ff=0;
    while(u&&t[u].val!=x)
        ff=u,u=t[u].ch[x>t[u].val];
    if(u) t[u].cnt++;
    else
    {
        u=++tot;
        if(ff) t[ff].ch[x>t[ff].val]=u;
        t[tot].cnt=1;
        t[tot].ff=ff,t[tot].val=x;
    }
    splay(u,0);
}
inline void find(int x)
{
    int u=root;
    if(!u) return;
    while(t[u].ch[t[u].val<x]&&t[u].val!=x)
        u=t[u].ch[t[u].val<x];
    splay(u,0);
}
inline int pre(int x,int f)
{
    find(x);
    int u=root;
    if((f&&t[u].val>x)||(!f&&t[u].val<x)) return u;
    u=t[u].ch[f];
    while(t[u].ch[f^1]) u=t[u].ch[f^1];
    return u;
}inline void del(int x)
{
    int last=pre(x,0);
    int nxt=pre(x,1);
    splay(last,0);splay(nxt,last);
    int u=t[nxt].ch[0];
    if(t[u].cnt>1) t[u].cnt--,splay(u,0);
    else t[nxt].ch[0]=0;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    insert(2147483647/3),insert(-2147483647/3);
    for(int i=1;i<=n;i++)
    {
        int op,x;
        scanf("%d%d",&op,&x);
        if(op==0)//pet
        {
            if(cnt>=0) insert(x);
            else
            {
                int a=t[pre(x,0)].val;
                int b=t[pre(x,1)].val;
                if(abs(a-x)<=abs(b-x)) ans+=abs(a-x),del(a),ans%=mod;
                else ans+=abs(b-x),del(b),ans%=mod;
            }
            cnt++;
        }
        else//people
        {
            if(cnt<=0) insert(x);
            else
            {
                int a=t[pre(x,0)].val;
                int b=t[pre(x,1)].val;
                if(abs(a-x)<=abs(b-x)) ans+=abs(a-x),del(a),ans%=mod;
                else ans+=abs(b-x),del(b),ans%=mod;
            }
            cnt--;
        }
    }
    printf("%lld\n",ans%mod);
    return 0;
}