luogu P2286 [HNOI2004]宠物收养场

在这里插入图片描述

analysis

显然嘛,建两颗平衡树,一颗对人来操作,一颗对动物来操作
其实建两颗平衡树真的不像我原来想象的那么麻烦(要复制粘贴一次??),其实只需要写一个类(class)封装一下就好了(结构体也可以,只是low了一点),只需要打一棵树的板子,然后命名两个类变量就好了,不然的话,建n颗树不是要复制粘贴n次??

这次打Splay打的比较顺利,交上去一遍过,可能是因为在提交前对拍了一下吧
不拍不知道,一排还吓一跳,我的inf又双叒出锅了。。
inf这次开了LONG_LONG_MAX-10,然后这个值和1291一加,再取个绝对值,就炸了。。
开INT_MAX吧,不大不小刚刚好

code

#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
const int mod=1000000;
template<typename T>void read(T &x){
    x=0;char r=getchar();T neg=1;
    while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
    while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
    x*=neg;
}
const int maxn=80000+10;
class BBT{
public:
    struct node{int f;int son[2];int siz;int cnt;ll w;}tree[maxn];
    int root,nfp;
    bool getpos(int pos){return tree[tree[pos].f].son[1]==pos;}
    void update(int pos){tree[pos].siz=tree[tree[pos].son[0]].siz+tree[tree[pos].son[1]].siz+tree[pos].cnt;}
    void Rotate(int x){
        int f=tree[x].f;
        int ff=tree[f].f;
        int posx=getpos(x),posf=getpos(f);
        int s=tree[x].son[posx^1];
        tree[x].f=ff;
        tree[ff].son[posf]=x;
        tree[x].son[posx^1]=f;
        tree[f].f=x;
        tree[f].son[posx]=s;
        tree[s].f=f;
        update(f);update(x);
    }
    void Splay(int pos,int to=0){
        int f,ff;
        while(tree[pos].f!=to){
            f=tree[pos].f;ff=tree[f].f;
            if(ff!=to)Rotate((getpos(pos)==getpos(f))?f:pos);
            Rotate(pos);
        }if(to==0)root=pos;
    }
    void Insert(ll w){
        int cur=root;int p=0;
        while(cur&&tree[cur].w!=w){p=cur;cur=tree[cur].son[w>tree[cur].w];}
        if(cur)++tree[cur].cnt;
        else{
            cur=++nfp;
            tree[cur].cnt=tree[cur].siz=1;
            tree[cur].f=p;tree[cur].son[0]=tree[cur].son[1]=0;
            tree[cur].w=w;
            if(p)tree[p].son[tree[p].w<w]=cur;
        }Splay(cur);
    }
    void Find(ll w){
        int cur=root;
        while(tree[cur].w!=w&&tree[cur].son[tree[cur].w<w])cur=tree[cur].son[tree[cur].w<w];
        Splay(cur);
    }
    int Pre(ll w){
        Find(w);
        if(tree[root].w<w)return root;
        int cur=tree[root].son[0];
        while(tree[cur].son[1])cur=tree[cur].son[1];
        Splay(cur);return cur;
    }
    int Bac(ll w){
        Find(w);
        if(tree[root].w>w)return root;
        int cur=tree[root].son[1];
        while(tree[cur].son[0])cur=tree[cur].son[0];
        Splay(cur);return cur;
    }
    void Delete(int w){
        int pre=Pre(w);
        int bac=Bac(w);
        Splay(pre),Splay(bac,pre);
        if(tree[tree[bac].son[0]].cnt>1)--tree[tree[bac].son[0]].cnt;
        else tree[bac].son[0]=0;
    }
    void initialize(){root=0;nfp=0;}
}Pet,Man;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>类
int n;
const ll inf=INT_MAX-100;
int main(){
    freopen("in.txt","r",stdin);
    Pet.initialize();Man.initialize();
    Pet.Insert(inf);
    Pet.Insert(-inf);
    Man.Insert(inf);
    Man.Insert(-inf);
    read(n);
    int ai;
    ll bi;
    int res=0;
    int nfP=0,nfM=0;
    loop(i,1,n){
        read(ai),read(bi);
        if(nfP==0&&nfM==0){
            if(ai==0)Pet.Insert(bi),++nfP;
            else if(ai==1)Man.Insert(bi),++nfM;
        }
        else{
            if(ai==0){
                if(nfP&&nfM==0){
                    Pet.Insert(bi);
                    ++nfP;
                }
                else if(nfP==0&&nfM){
                    int pre=Man.Pre(bi);
                    int bac=Man.Bac(bi);
                    if(abs(Man.tree[pre].w-bi)<=abs(Man.tree[bac].w-bi))
                        Man.Delete(Man.tree[pre].w),res=(res+abs(Man.tree[pre].w-bi))%mod;
                    else if(abs(Man.tree[pre].w-bi)>abs(Man.tree[bac].w-bi))
                        Man.Delete(Man.tree[bac].w),res=(res+abs(Man.tree[bac].w-bi))%mod;
                    --nfM;
                }
            }
            else if(ai==1){
                if(nfP&&nfM==0){
                    int pre=Pet.Pre(bi);
                    int bac=Pet.Bac(bi);
                    if(abs(Pet.tree[pre].w-bi)<=abs(Pet.tree[bac].w-bi))
                        Pet.Delete(Pet.tree[pre].w),res=(res+abs(Pet.tree[pre].w-bi))%mod;//inf再次背锅 
                    else if(abs(Pet.tree[pre].w-bi)>abs(Pet.tree[bac].w-bi))
                        Pet.Delete(Pet.tree[bac].w),res=(res+abs(Pet.tree[bac].w-bi))%mod;
                    --nfP;
                }
                else if(nfP==0&&nfM){
                    Man.Insert(bi);
                    ++nfM;
                }
            }
        }
    }
    printf("%d\n",res);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndrewMe8211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值