【bzoj 1588】 [HNOI2002]营业额统计

来源:互联网 发布:手机电脑文件软件 编辑:程序博客网 时间:2024/06/05 06:34

1588: [HNOI2002]营业额统计

Time Limit: 5 Sec  Memory Limit: 162 MB
Submit: 15167  Solved: 5955
[Submit][Status][Discuss]

Description

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

Input

第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i
天公司的营业额。
天数n<=32767,
每天的营业额ai <= 1,000,000。
最后结果T<=2^31

Output

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

Sample Input

6
5
1
2
5
4
6

Sample Output

12

splay 学习1

#include<cstdio>using namespace std;#define N 100005#define inf 0x3f3f3f3f#define min(a,b) ((a)<(b)?(a):(b))int pre[N],key[N],ch[N][2],root,tot;int n;void NewNode(int &r,int father,int k){    r=++tot;    pre[r]=father;    key[r]=k;    ch[r][0]=ch[r][1]=0;}void Rotate(int x,int kind){    int y=pre[x];    ch[y][!kind]=ch[x][kind];    pre[ch[x][kind]]=y;    if(pre[y])        ch[pre[y]][ch[pre[y]][1]==y]=x;    pre[x]=pre[y];    ch[x][kind]=y;    pre[y]=x;}void Splay(int r,int goal){    while(pre[r]!=goal)    {        if(pre[pre[r]] == goal)            Rotate(r,ch[pre[r]][0]==r);        else{            int y=pre[r];            int kind=ch[pre[y]][0]==y;            if(ch[y][kind]==r){                Rotate(r,!kind);                Rotate(r,kind);            }            else{                Rotate(y,kind);                Rotate(r,kind);            }        }    }    if(goal==0)root=r;}int Insert(int k){    int r=root;    while(ch[r][key[r]<k])    {        if(key[r]==k){            Splay(r,0);            return 0;        }        r=ch[r][key[r]<k];    }    NewNode(ch[r][k>key[r]],r,k);    Splay(ch[r][k>key[r]],0);    return 1;}int get_pre(int x){    int tmp=ch[x][0];    if(tmp==0)return inf;    while(ch[tmp][1])    {        tmp=ch[tmp][1];    }    return key[x]-key[tmp];}int get_next(int x){    int tmp=ch[x][1];    if(tmp==0)return inf;    while(ch[tmp][0])    {        tmp=ch[tmp][0];    }    return key[tmp]-key[x];}int main(){    while(scanf("%d",&n)!=-1)    {        root=tot=0;        int ans=0;        for(int i=1;i<=n;i++){            int num;            if(scanf("%d",&num)==-1) num=0;            if(i==1){                ans+=num;                NewNode(root,0,num);                continue;            }            if(Insert(num)==0)continue;            int a=get_next(root);            int b=get_pre(root);            ans+=min(a,b);        }        printf("%d\n",ans);    }    return 0;}


0 0