码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ_1208Codevs_1258_[HNOI2004]_宠物收养所(Treap/Splay)

时间:2016-05-13 19:07:11      阅读:339      评论:0      收藏:0      [点我收藏+]

标签:

描述


http://www.lydsy.com/JudgeOnline/problem.php?id=1208

(据说codevs要更新?就不放codevs的地址了吧...)

有宠物和人,每个单位都有一个与其他单位不同的值(正),如果现在有宠物,来了一个人,人取走和他的值最接近的宠物(如果有两个选值小的),如果现在有人,来了一个宠物,和它值最接近的人(如果有两个选值小的)取走它.求每次带宠物走两个单位的值的差的绝对值的总和.

 

分析


用平衡树查找前驱和后驱即可.依照题意,要么全是人要么全是宠物,所以建一棵树即可.模板题.

注意:

1.判断是否有前驱或后驱时要小心.

 

p.s.第一道用Splay写的题,调了好久...指针理解的不是很好啊.

 

 

技术分享
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int oo=~0u>>1;

struct Treap{
    struct node{
        node* ch[2];
        int v,r,s;
        node(int v,node* t):v(v){ ch[0]=ch[1]=t; r=rand(); s=1; }
        void push_up(){ s=ch[0]->s+ch[1]->s+1; }
    }*root,*null;
    Treap(){
        null=new node(0,NULL); null->s=0; null->r=oo;
        root=null;
    }
    void rot(node* &o,bool d){
        node* k=o->ch[!d]; o->ch[!d]=k->ch[d]; k->ch[d]=o;
        o->push_up(); k->push_up(); o=k;
    }
    void insert(node* &o,int x){
        if(o==null) o=new node(x,null);
        else{
            bool d=x>o->v;
            insert(o->ch[d],x);
            if(o->ch[d]->r<o->r) rot(o,!d);
            o->push_up();
        }
    }
    void remove(node* &o,int x){
        if(o->v==x){
            if(o->ch[0]!=null&&o->ch[1]!=null){
                bool d=o->ch[0]->r<o->ch[1]->r;
                rot(o,d); remove(o->ch[d],x);
                o->push_up();
            }
            else{
                node* u=o;
                if(o->ch[0]==null) o=o->ch[1]; else o=o->ch[0];
                delete u;
            }
        }
        else{
            bool d=x>o->v;
            remove(o->ch[d],x);
            o->push_up();
        }
    }
    int pre(int x){
        node* t=root;
        int ret=-1;
        while(t!=null){
            if(t->v<x) ret=t->v,t=t->ch[1];
            else t=t->ch[0];
        }
        return ret;
    }
    int suc(int x){
        node* t=root;
        int ret=-1;
        while(t!=null){
            if(t->v>x) ret=t->v,t=t->ch[0];
            else t=t->ch[1];
        }
        return ret;
    }
}tree;

const int maxn=80000+5,mod=1e6;
int n;
int main(){
    scanf("%d",&n);
    int cnt=0,now,ans=0;
    while(n--){
        int a,b;
        scanf("%d%d",&a,&b);
        if(cnt==0) now=a;
        if(a==now){
            tree.insert(tree.root,b);
            cnt++;
        }
        else{
            int pre=tree.pre(b);
            int suc=tree.suc(b);
            if(pre==-1){
                int    t=suc-b;
                ans=(ans+t)%mod;
                tree.remove(tree.root,suc);
            }
            else if(suc==-1){
                int t=b-pre;
                ans=(ans+t)%mod;
                tree.remove(tree.root,pre);
            }
            else{
                int t1=b-pre,t2=suc-b;
                if(t1<=t2){
                    ans=(ans+t1)%mod;
                    tree.remove(tree.root,pre);
                }
                else{
                    ans=(ans+t2)%mod;
                    tree.remove(tree.root,suc);
                }
            }
            cnt--;
        }
    }
    printf("%d\n",ans);
    return 0;
}
Treap

 

技术分享
#include <cstdio>
#include <algorithm>
using namespace std;

struct Splay{
    struct node{
        node* ch[2],*pa;
        int v;
        node(int v,node* t):v(v){ ch[0]=ch[1]=pa=t; }
        bool d(){ return pa->ch[1]==this; }
        void setc(node* t,bool d) { ch[d]=t; t->pa=this; }
    }*root,*null;
    Splay(){
        null=new node(0,NULL);
        root=null;
    }
    void rot(node* o){
        node* pa=o->pa; bool d=o->d();
        pa->pa->setc(o,pa->d());
        pa->setc(o->ch[!d],d);
        o->setc(pa,!d);
        if(pa==root) root=o;
    }
    void splay(node* o,node* pa){
        while(o->pa!=pa){
            if(o->pa->pa==pa) rot(o);
            else o->d()==o->pa->d()?(rot(o->pa),rot(o)):(rot(o),rot(o));
        }
    }
    void insert(int x){
        if(root==null){ root=new node(x,null); return; }
        node* t=root;
        while(t->ch[x>t->v]!=null&&t->ch[x>t->v]->v!=x) t=t->ch[x>t->v];
        if(t->ch[x>t->v]!=null) return;
        node* k=new node(x,null);
        t->setc(k,x>t->v);
        splay(k,null);
    }
    int pre(int x){
        node* t=root;
        int ret=-1;
        while(t!=null){
            if(t->v<=x) ret=t->v,t=t->ch[1];
            else t=t->ch[0];
        }
        return ret;
    }
    int suc(int x){
        node* t=root;
        int ret=-1;
        while(t!=null){
            if(t->v>=x) ret=t->v,t=t->ch[0];
            else t=t->ch[1];
        }
        return ret;
    }
}tree;

int n,a,ans;

int main(){
    scanf("%d",&n);
    scanf("%d",&a);
    ans+=a; tree.insert(a); n--;
    while(n--){
        scanf("%d",&a);
        int pre=tree.pre(a);
        int suc=tree.suc(a);
        if(pre==-1) ans+=suc-a;
        else if(suc==-1) ans+=a-pre;
        else ans+=min(suc-a,a-pre);
        tree.insert(a);
    }
    printf("%d\n",ans);
    return 0;
}
Splay

 

BZOJ_1208Codevs_1258_[HNOI2004]_宠物收养所(Treap/Splay)

标签:

原文地址:http://www.cnblogs.com/Sunnie69/p/5490334.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!