zoukankan      html  css  js  c++  java
  • [BZOJ 1208] 宠物收养所

    Link:

    BZOJ 1208 传送门

    Solution:

    求前驱后继,很明显的平衡树操作

    其实$set$完全可以做,主要是为了复习下$Treap$结果调了好久……

    注意:在写平衡树删除时一定要记得考虑删除数不存在的情况

    特别是$Treap$,如果访问到空要直接返回否则死循环……

    Code:

    #include <bits/stdc++.h>
     
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    typedef double db;
    const int MAXN=1e5+10,MOD=1e6,INF=1<<30;
     
    namespace Treap
    {
        int tot,rt;
        int sz[MAXN],pri[MAXN],val[MAXN],s[MAXN][2];
         
        void Pushup(int x)
        {sz[x]=sz[s[x][0]]+sz[s[x][1]]+1;}
        void Rotate(int &x,int f)
        {//注意这里的旋转 
            int tmp=s[x][f];
            s[x][f]=s[tmp][f^1];s[tmp][f^1]=x;
            Pushup(x);Pushup(x=tmp);
        }
        void Insert(int &x,int k)
        {
            if(!x)
            {
                x=++tot;
                pri[x]=rand();val[x]=k;
                sz[x]=1;return;
            }
             
            int nxt=k>val[x];Insert(s[x][nxt],k);
            if(pri[x]>pri[s[x][nxt]]) Rotate(x,nxt);
            Pushup(x);
        }
        int Pre(int &x,int k)
        {
            if(!x) return -INF;
            if(k==val[x]) return val[x];
            if(k>val[x]) return max(val[x],Pre(s[x][1],k));
            else return Pre(s[x][0],k); 
        }
        int Nxt(int &x,int k)
        {
            if(!x) return INF;
            if(k==val[x]) return val[x];
            if(k<val[x]) return min(val[x],Nxt(s[x][0],k));
            else return Nxt(s[x][1],k);
        }
        void Del(int &x,int k)
        {
            if(!x) return;//防止k不存在! 
            if(val[x]==k)
            {
                if(s[x][0]*s[x][1]==0)
                {x=s[x][0]+s[x][1];return;}
                int nxt=pri[s[x][0]]<pri[s[x][1]];
                Rotate(x,nxt^1);Del(s[x][nxt],k);
            }
            else Del(s[x][k>val[x]],k);
            Pushup(x);
        }
    }
    using namespace Treap;
    int n,x,y,cur,cnt,res;
     
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            if(!cnt||cur==x)
                cnt++,cur=x,Insert(rt,y);
            else
            {
                int pre=Pre(rt,y),nxt=Nxt(rt,y),tmp;
                if(nxt-y<y-pre) tmp=nxt-y,Del(rt,nxt);
                else tmp=y-pre,Del(rt,pre);
                cnt--;(res+=tmp)%=MOD;
            }
        }
        printf("%d",res);
        return 0;
    }
  • 相关阅读:
    由“Jasperrpeorts 4.1.2升级到5.1.2对flex项目的解析”到AS3 带命名空间的XML的操作
    c++里的类型转化
    A股市场暴跌背后的三大元凶?
    jQuery简单过滤选择器
    Handling of asynchronous events---reference
    NMAP
    JVM Run-Time Data Areas--reference
    Getting over the dangers of rm command in Linux---reference
    45 Useful Oracle Queries--ref
    手动修改user-agent
  • 原文地址:https://www.cnblogs.com/newera/p/9637536.html
Copyright © 2011-2022 走看看