BZOJ1588: [HNOI2002]营业额统计[BST]

1588: [HNOI2002]营业额统计

Time Limit: 5 Sec  Memory Limit: 162 MB
Submit: 14151  Solved: 5366
[Submit][Status][Discuss]

Description

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

Input

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

Output

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


 

 

找前驱和后继,注意可以相同

方法很多,此处练习splay

//
//  main.cpp
//  hnoi2002营业额统计
//
//  Created by Candy on 28/11/2016.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define pa t[x].fa
#define lc t[x].ch[0]
#define rc t[x].ch[1]
const int N=1e5+5,INF=1e9+233;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct node{
    int ch[2],fa,v,w,size;
}t[N];
int cnt,root;
inline int wh(int x){return t[pa].ch[1]==x;}
inline void update(int x){t[x].size=t[lc].size+t[rc].size+t[x].w;}
inline int nw(int v){
    cnt++;t[cnt].v=v;t[cnt].ch[0]=t[cnt].ch[1]=t[cnt].fa=0;
    t[cnt].w=t[cnt].size=1;
    return cnt;
}
inline void rotate(int x){
    int f=t[x].fa,g=t[f].fa,c=wh(x);
    if(g) t[g].ch[wh(f)]=x;
    t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f;
    t[x].ch[c^1]=f;t[f].fa=x;
    t[x].fa=g;
    update(f);update(x);
}
inline void splay(int x,int tar){
    for(;t[x].fa!=tar;rotate(x))
        if(t[pa].fa!=tar) rotate(wh(x)==wh(pa)?pa:x);
    if(tar==0) root=x;
}
inline void ins(int v){
    if(root==0) {root=nw(v);return;}
    int x=root,last=0;
    while(x!=0){
        if(v==t[x].v){t[x].w++;t[x].size++;return;}
        last=x;
        if(v<t[x].v) x=lc;else x=rc;
    }
    if(v<t[last].v) t[last].ch[0]=nw(v);
    else t[last].ch[1]=nw(v);
    t[cnt].fa=last;update(last);
    splay(cnt,0);
}
inline int spre(int v){
    int x=root,ans=0;
    while(x!=0){
        if(v>=t[x].v) ans=x,x=rc;
        else x=lc;
    }
    return ans;
}
inline int snxt(int v){
    int x=root,ans=0;
    while(x!=0){
        if(v<=t[x].v) ans=x,x=lc;
        else x=rc;
    }
    return ans;
}
int n,a,ans;
int main(int argc, const char * argv[]) {
    n=read();t[0].v=INF;
    n--;a=read();ans=a;ins(a);
    while(n--){
        a=read();
        int t1=t[spre(a)].v,t2=t[snxt(a)].v,mn=INF;
        if(t1!=INF) mn=min(mn,a-t1);
        if(t2!=INF) mn=min(mn,t2-a);
        ans+=mn;//printf("hi%d %d %d %d\n",a,t1,t2,mn);
        ins(a);
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2016-11-28 23:21  Candy?  阅读(271)  评论(0编辑  收藏  举报