bzoj1588: [HNOI2002]营业额统计 treap

原来treap这么简单。。。比splay简单多了。。。。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,a;
struct Node
{
    Node *ch[2];
    int r,v;
    Node()
    {
        ch[0]=ch[1]=NULL;
        r=rand();v=0;
    }
};Node *rt;

void Free(Node *o)
{
    if(o==NULL) return;
    Free(o->ch[0]);
    Free(o->ch[1]);
    delete o;
}

void rot(Node* &o,int d)
{
    Node* k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]=o;
    o=k;
}

void Insert(Node* &o,int x)
{
    if(o==NULL){
        o=new Node();
        o->v=x;
        return;
    }
    if(o->v==x) return;
    int d=x<o->v?0:1;
    Insert(o->ch[d],x);
    if(o->ch[d]->r>o->r) rot(o,d^1);
}

int Find(Node* &o,int x)
{
    if(o==NULL) return 0;
    if(o->v==x) return 1;
    if(x<o->v) return Find(o->ch[0],x);
    else return Find(o->ch[1],x);
}

int getpre(Node* &o,int x)
{
    if(o==NULL) return -INF;
    if(x<=o->v) return getpre(o->ch[0],x);
    else return max(o->v,getpre(o->ch[1],x));
}

int getnext(Node* &o,int x)
{
    if(o==NULL) return INF;
    if(x>=o->v) return getnext(o->ch[1],x);
    else return min(o->v,getnext(o->ch[0],x));
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n){
        Free(rt);
        int ans=0;
        REP(i,1,n){
            if(scanf("%d",&a)==EOF) a=0;
            if(i==1) ans+=a;
            else{
                int b=Find(rt,a);
                if(b==1) ;
                else{
                    int x=getpre(rt,a),y=getnext(rt,a);
                    ans+=min(a-x,y-a);
                }
            }
            Insert(rt,a);
        }
        cout<<ans<<endl;
        Free(rt);
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/--560/p/5238226.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值