HNOI2002 营业额统计

传送门

学了splay,我们来做一做splay的裸题吧!

这道题还是十分的简单的。首先第一天的波动值就是当天的营业额,然后其他的,每次就直接在splay里面查找前驱后继,把与当前值差值绝对值小的那个加到答案里面就行。哦,还有就是如果已经存在过这个值那么+0即可(我的找前驱后继好像不支持相同的数……所以我在插入的时候判断了一下)

其他就没啥了……splay写的不熟练就orz了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 100005;
const int N = 10000005;
const int INF = 1000000009;
 
int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
    if(ch == '-') op = -1;
    ch = getchar();
    }
    while(ch >='0' && ch <= '9')
    {
    ans *= 10;
    ans += ch - '0';
    ch = getchar();
    }
    return ans * op;
}

struct node
{
    int fa,ch[2],son,cnt,val;
}t[M<<2];

int n,x,tot,idx,root;

bool get(int x)
{
    return t[t[x].fa].ch[1] == x;
}

void pushup(int x)
{
    t[x].son = t[t[x].ch[0]].son + t[t[x].ch[1]].son + t[x].cnt;
}

void rotate(int x)
{
    int y = t[x].fa,z = t[y].fa,k = get(x);
    t[z].ch[t[z].ch[1] == y] = x,t[x].fa = z;
    t[y].ch[k] = t[x].ch[k^1],t[t[y].ch[k]].fa = y;
    t[x].ch[k^1] = y,t[y].fa = x;
    pushup(x),pushup(y);
}

void splay(int x,int goal)
{
    while(t[x].fa != goal)
    {
    int y = t[x].fa,z = t[y].fa;
    if(z != goal) (t[y].ch[0] == x) ^ (t[z].ch[0] == y) ? rotate(x) : rotate(y);
    rotate(x);
    }
    if(goal == 0) root = x;
}

bool insert(int x)
{
    int u = root,f = 0;
    bool flag = 0;
    while(u && t[u].val != x) f = u,u = t[u].ch[x > t[u].val];
    if(u) t[u].cnt++,flag = 1;
    else
    {
    u = ++idx;
    if(f) t[f].ch[x > t[f].val] = u;
    t[u].ch[0] = t[u].ch[1] = 0;
    t[u].fa = f,t[u].val = x,t[u].cnt = t[u].son = 1;
    }
    splay(u,0);
    return flag;
}

void find(int x)
{
    int u = root;
    if(!u) return;
    while(t[u].ch[x > t[u].val] && t[u].val != x) u = t[u].ch[x > t[u].val];
    splay(u,0);
}

int next(int x,int f)
{
    find(x);
    int u = root;
    if((x > t[u].val && f) || (x < t[u].val && !f)) return t[u].val;
    u = t[u].ch[f];
    while(t[u].ch[f^1]) u = t[u].ch[f^1];
    return t[u].val;
}

int main()
{
    n = read();
    insert(INF),insert(-INF);
    x = read(),insert(x),tot += x;
    rep(i,2,n)
    {
    x = read();
    if(insert(x)) continue;
    int a = next(x,0),b = next(x,1);
    tot += min(abs(x-a),abs(x-b));
//    printf("#%d\n",tot);
    }
    printf("%d\n",tot);
    return 0;
}

 

posted @ 2018-10-02 22:14  CaptainLi  阅读(163)  评论(0编辑  收藏  举报