zoukankan      html  css  js  c++  java
  • BZOJ1208_宠物收养所_KEY

    题目传送门

    平衡树的题。

    因为题目给出条件(其实自己也知道):同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个。

    所以只要维护一颗平衡树,它的里面要不全是人,要不全是宠物。

    找到人的前驱后继比较。

    code:

    /**************************************************************
        Problem: 1208
        User: yekehe
        Language: C++
        Result: Accepted
        Time:180 ms
        Memory:2388 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
     
    int read()
    {
        char c;while(c=getchar(),c<'0'||c>'9');
        int x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';
        return x;
    }
     
    int N,now,root,cnt,dist;
    int tr[80005][2],v[80005],r[80005],f[80005];
     
    void clear(int x){f[x]=tr[x][0]=tr[x][1]=r[x]=v[x]=0;}
    void up(int x){f[x]=f[tr[x][0]]+f[tr[x][1]];}
    int abs(int x){return x>0?x:-x;}
     
    void rotate(int &x,int o)
    {
        int k=tr[x][o];
        tr[x][o]=tr[k][o^1];
        tr[k][o^1]=x;
        f[k]=f[x];
        up(x);
        x=k;
    }
     
    void insert(int &x,int val)
    {
        if(!x){
            x=++cnt;
            v[x]=val;
            r[x]=rand();
            f[x]++;
            return ;
        }
        int to=val>v[x];
        insert(tr[x][to],val);
        if(r[x]>r[tr[x][to]])rotate(x,to);
        return ;
    }
     
    void del(int &x,int val)
    {
        if(v[x]==val){
            if(!(tr[x][0]+tr[x][1])){
                clear(x);x=0;
                return ;
            }
            if(!(tr[x][0]*tr[x][1])){
                int w=tr[x][0]+tr[x][1];
                clear(x);x=w;
                return ;
            }
            rotate(x,0);
            del(x,val);
            return ;
        }
        f[x]--;
        int to=val>v[x];
        del(tr[x][to],val);
        up(x);
        return ;
    }
     
    void pre(int x,int val)//前驱
    {
        if(!x)return ;
        if(v[x]>=val)pre(tr[x][0],val);
        else{
            dist=x;
            pre(tr[x][1],val);
        }
    }
     
    void bac(int x,int val)//后继
    {
        if(!x)return ;
        if(v[x]<=val)bac(tr[x][1],val);
        else{
            dist=x;
            bac(tr[x][0],val);
        }
    }
     
    int main()
    {
        srand(23333);
        N=read();
        int i,ans=0,o1,o2,tot=0;
            for(i=1;i<=N;i++){
                int x=read(),y=read();
                if(!tot){insert(root,y),now=x;tot++;continue;}
                if(now==x)insert(root,y),tot++;
                else{
                    dist=0;pre(root,y);o1=dist;
                    dist=0;bac(root,y);o2=dist;
                    if(!o1&&!o2)continue;
                    int k1=o1?y-v[o1]:2e9,k2=o2?v[o2]-y:2e9;
                    dist=k1>k2?o2:o1;//找较接近的值
                    ans=(ans+abs(v[dist]-y))%1000000;
                    del(root,v[dist]);
                    tot--;
                }
            }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    用Inno Setup来解决.NetFramework安装问题
    NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者
    NSIS
    Nullsoft教程 NSIS初学者图文教程一
    flex 实例Demo
    计算机组成原理
    Spring知识点提炼
    JAVA Web从前端到后台常用框架介绍
    使用navicat将mysql转换成sqlserver
    JDK 5 ~ 10 新特性倾情整理!
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8592492.html
Copyright © 2011-2022 走看看