【bzoj1588】[HNOI2002]营业额统计 Splay

Description

营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。  输入输出要求

Input

第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i天公司的营业额。

Output

输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。

Sample Input

6

5

1

2

5

4

6   

Sample Output

12

HINT

结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12

此题数据有问题,详见讨论版http://www.lydsy.com/JudgeOnline/wttl/wttl.php?pid=1588

Source

每次找前驱后继加起来即可…
好像数据有问题,输入时先赋值为0即可。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

const int SZ = 1000010;
const int INF = 1000000010;

struct node{
    node *ch[2],*f;
    int v,sz,cnt;

    void maintain()
    {
        sz = ch[0] -> sz + ch[1] -> sz + cnt; 
    }

    void setc(node *x,int d)
    {
        (ch[d] = x) -> f = this;
    }

    int cmp(int x)
    {
        if(x == v) return -1;
        return x < v ? 0 : 1;
    }

    int dir()
    {
        return f -> ch[1] == this;
    }

}T[SZ], *root, *null;

int Tcnt = 0;

node* newnode(int x,node *f)
{
    node *k = T + (Tcnt ++);
    k -> ch[1] = k -> ch[0] = null;
    k -> cnt = k -> sz = 1;
    k -> f = f;
    k -> v = x;
    return k;
}

void rotate(node *p)
{
    node *fa = p -> f;
    int d = p -> dir();
    fa -> f -> setc(p,fa -> dir());
    fa -> setc(p -> ch[d ^ 1],d); fa -> maintain();
    p -> setc(fa,d ^ 1); p -> maintain();
    if(root == fa) root = p;
}

void splay(node *p,node *rt = null)
{
    while(p -> f != rt)
    {
        if(p -> f -> f == rt) rotate(p);
        else p -> dir() == p -> f -> dir() ? (rotate(p -> f),rotate(p)) : (rotate(p),rotate(p));
    }
}

void insert(node *p,int x)
{
    if(root == null) { root = newnode(x,null); return ; }
    while(p != null)
    {
        p -> sz ++;
        int d = p -> cmp(x);
        if(d == -1) { p -> cnt ++; break; }
        if(p -> ch[d] == null)
        {
            p -> ch[d] = newnode(x,p);
            p = p -> ch[d];
            break; 
        }
        p = p -> ch[d];
    }
    splay(p);
}

int ask_pre(node *p,int x)
{
    int ans = INF;
    while(p != null)
    {
        if(p -> v <= x) 
            ans = p -> v, p = p -> ch[1];
        else 
            p = p -> ch[0];
    }
    return ans;
}

int ask_suf(node *p,int x)
{
    int ans = INF;
    while(p != null)
    {
        if(p -> v >= x) 
            ans = p -> v, p = p -> ch[0];
        else 
            p = p -> ch[1];
    }
    return ans;
}

void init()
{
    null = newnode(-INF,null);
    null -> sz = null -> cnt = 0;
    root = null;
}

int main()
{
    init();
    int ans = 0;
    int n;
    scanf("%d",&n);
    while(n --)
    {
        int x = 0;
        scanf("%d",&x);
        if(root -> sz)
            ans += min(abs(x - ask_pre(root,x)),abs(x - ask_suf(root,x)));
        else 
            ans = x;
        insert(root,x);
    }
    printf("%d",ans);
    return 0;
}


你可能感兴趣的:(splay)