[HNOI2002]营业额统计

treap板子题。

前驱后继查询。

代码:

#include<ctime>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define N 33000
int n,a;
int rt,tot;
struct Treap
{
    int ls,rs;
    int siz,w,rnd,v;
}tr[N];
void update(int u)
{
    tr[u].siz = tr[tr[u].ls].siz + tr[tr[u].rs].siz + tr[u].w;
}
void lturn(int &x)
{
    int y = tr[x].rs;
    tr[x].rs = tr[y].ls;
    tr[y].ls = x;
    tr[y].siz = tr[x].siz;
    update(x);
    x=y;
}
void rturn(int &x)
{
    int y = tr[x].ls;
    tr[x].ls = tr[y].rs;
    tr[y].rs = x;
    tr[y].siz = tr[x].siz;
    update(x);
    x=y;
}
void insert(int &k,int x)
{
    if(!k)
    {
        k = ++tot;
        tr[k].siz = tr[k].w = 1;
        tr[k].v = x,tr[k].rnd = rand();
        return ;
    }
    tr[k].siz++;
    if(tr[k].v==x)
    {
        tr[k].w++;
        return ;
    }else if(tr[k].v<x)
    {
        insert(tr[k].rs,x);
        if(tr[tr[k].rs].rnd<tr[k].rnd)lturn(k);
    }else
    {
        insert(tr[k].ls,x);
        if(tr[tr[k].ls].rnd<tr[k].rnd)rturn(k);
    }
}
int ans = 0;
void qq(int u,int x)
{
    if(!u)return ;
    if(tr[u].v<=x)
    {
        ans = tr[u].v;
        qq(tr[u].rs,x);
    }else qq(tr[u].ls,x);
}
void hj(int u,int x)
{
    if(!u)return ;
    if(tr[u].v>=x)
    {
        ans = tr[u].v;
        hj(tr[u].ls,x);
    }else hj(tr[u].rs,x);
}
int main()
{
    srand(time(NULL));
    scanf("%d",&n);
    int as = 0;
    insert(rt,-2000005);
    insert(rt,2000005);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a);
        if(i==1)
        {
            insert(rt,a);
            as+=a;
            continue;
        }
        ans = -2000005;
        qq(rt,a);
        int tmp = a-ans;
        ans = 2000005;
        hj(rt,a);
        tmp = tmp<(ans-a)?tmp:(ans-a);
        as+=tmp;
        insert(rt,a);
    }
    printf("%d\n",as);
    return 0;
}

 

posted @ 2018-09-05 19:19  LiGuanlin  阅读(126)  评论(0编辑  收藏  举报