BZOJ[1208][HNOI2004]宠物收养所 Treap

来源:互联网 发布:网络传播方面的论文 编辑:程序博客网 时间:2024/04/29 15:04

题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=1208

开两个平衡树,找前驱后继操作和正常的一样..
用Treap是因为好写

代码如下:

#include<algorithm>#include<cstdlib>#include<ctype.h>#include<cstdio>#define INF 2147483647using namespace std;const int Root=19260817;inline int read(){    int x=0,f=1;char c;    do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));    do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));    return x*f;}struct Node{    int siz,cnt,pri,x;    Node *ch[2];    Node(int);    inline int cmp(int k){        if(k==x) return -1;        return k<x?0:1;    }    inline void maintain(){        siz=ch[0]->siz+ch[1]->siz+cnt;        return;    }}*null,*root[2];Node::Node(int _):x(_){    pri=rand();    siz=cnt=1;    ch[0]=ch[1]=null;}inline void Rotate(Node *&x,int d){    Node *k=x->ch[d^1];    x->ch[d^1]=k->ch[d];    k->ch[d]=x;    x->maintain();k->maintain();    x=k;}void Insert(Node *&x,int k){    if(x==null){        x=new Node(k);        return;    }    int d=x->cmp(k);    if(!~d) x->cnt++,x->siz++;    else{        Insert(x->ch[d],k);x->maintain();        if(x->pri < x->ch[d]->pri) Rotate(x,d^1);    }}void Delete(Node *&x,int k){    int d=x->cmp(k);    if(~d){        Delete(x->ch[d],k);        x->maintain();        return;    }    else{        if(x->cnt>1) x->cnt--;        else{            int p=x->ch[0]==null?1:(x->ch[1]==null?0:-1);            if(!~p){                p=x->ch[0]->pri > x->ch[1]->pri ? 1 : 0;                Rotate(x,p);Delete(x->ch[p],k);            }            else{                Node* cach=x;                x=x->ch[p];                delete cach;            }        }        x->maintain();    }}Node *Lower(Node *x,int k){    if(x==null) return x;    if(x->x>k) return Lower(x->ch[0],k);    Node *a=Lower(x->ch[1],k);    if(a==null || x->x>a->x) return x;    return a;}Node *Upper(Node *x,int k){    if(x==null) return x;    if(x->x<k) return Upper(x->ch[1],k);    Node *a=Upper(x->ch[0],k);    if(a==null || x->x<a->x) return x;    return a;}int n,x,y,sum;int main(){    srand(Root);    null=new Node(-INF);    null->ch[0]=null->ch[1]=null;    null->cnt=null->siz=0;    root[0]=root[1]=null;    n=read();    for(int i=1;i<=n;i++){        x=read();y=read();        if(!root[x^1]->siz)            Insert(root[x],y);        else{            Node *a=Lower(root[x^1],y);            Node *b=Upper(root[x^1],y);            if(a==null || b->x-y<y-a->x){                sum=(sum+b->x-y)%1000000;                Delete(root[x^1],b->x);            }            else{                sum=(sum+y-a->x)%1000000;                Delete(root[x^1],a->x);            }        }    }    printf("%d",sum);return 0;}
阅读全文
1 0
原创粉丝点击