1588: [HNOI2002]营业额统计 (splay tree)

1588: [HNOI2002]营业额统计

Time Limit: 5 Sec  
Memory Limit: 162 MB

Submit: 5783  
Solved: 1859

[
Submit][
Status]

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

Source

  [
Submit][
Status]

HOME Back

 

 

 

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013/8/24 10:57:20
  4 File Name     :F:\2013ACM练习\专题学习\splay_tree_2\营业额统计.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 
 21 #define Key_value ch[ch[root][1]][0]
 22 const int MAXN = 1000010;
 23 int pre[MAXN],ch[MAXN][2],key[MAXN];
 24 int root,tot1;
 25 
 26 int s[MAXN],tot2;//内存池
 27 
 28 void NewNode(int &r,int father,int k)
 29 {
 30     if(tot2) r = s[tot2--];//取的时候是tot2--,存的时候就要是++tot2
 31     else r = ++tot1;//这个必须是++tot1
 32     pre[r] = father;
 33     ch[r][0] = ch[r][1] = 0;
 34     key[r] = k;
 35 }
 36 //初始化
 37 void Init()
 38 {
 39     root = tot1 = tot2 = 0;
 40     ch[root][0] = ch[root][1] = key[root] = pre[root] = 0;
 41 }
 42 //旋转,0为左旋,1为右旋
 43 void Rotate(int x,int kind)
 44 {
 45     int y = pre[x];
 46     ch[y][!kind] = ch[x][kind];
 47     pre[ch[x][kind]] = y;
 48     if(pre[y])
 49         ch[pre[y]][ch[pre[y]][1]==y] = x;
 50     pre[x] = pre[y];
 51     ch[x][kind] = y;
 52     pre[y] = x;
 53 }
 54 //Splay调整,将r结点调整到goal下面
 55 void Splay(int r,int goal)
 56 {
 57     while(pre[r] != goal)
 58     {
 59         if(pre[pre[r]]==goal)
 60             Rotate(r,ch[pre[r]][0] ==r);
 61         else
 62         {
 63             int y = pre[r];
 64             int kind = ch[pre[y]][0]==y;
 65             if(ch[y][kind] == r)
 66             {
 67                 Rotate(r,!kind);
 68                 Rotate(r,kind);
 69             }
 70             else
 71             {
 72                 Rotate(y,kind);
 73                 Rotate(r,kind);
 74             }
 75         }
 76     }
 77     if(goal == 0)root = r;
 78 }
 79 
 80 void Insert(int k)//插入一个值为k的结点(有重复插入)
 81 {
 82     int r = root;
 83     if(r == 0)
 84     {
 85         NewNode(root,0,k);
 86         return;
 87     }
 88     while(ch[r][key[r]<k])
 89         r = ch[r][key[r]<k];
 90     NewNode(ch[r][key[r]<k],r,k);
 91     Splay(ch[r][key[r]<k],0);//转到根部
 92 }
 93 //找前驱
 94 int Get_pre(int r)
 95 {
 96     if(ch[r][0] == 0)return -1;//不存在
 97     r = ch[r][0];
 98     while(ch[r][1])r = ch[r][1];
 99     return r;
100 }
101 //找后继
102 int Get_next(int r)
103 {
104     if(ch[r][1] == 0)return -1;
105     r = ch[r][1];
106     while(ch[r][0])r = ch[r][0];
107     return r;
108 }
109 const int INF = 0x3f3f3f3f;
110 
111 int main()
112 {
113     //freopen("in.txt","r",stdin);
114     //freopen("out.txt","w",stdout);
115     int n;
116     while(scanf("%d",&n) == 1)
117     {
118         Init();
119         int a;
120         int ans = 0;
121         for(int i = 0;i < n;i++)
122         {
123             if(scanf("%d",&a) == EOF)  a= 0;
124             Insert(a);
125             if(i == 0)
126                 ans += a;
127             else
128             {
129                 int tmp = INF;
130                 int t1 = Get_pre(root);
131                 if(t1 != -1)
132                     tmp = min(tmp,key[root] - key[t1]);
133                 int t2 = Get_next(root);
134                 if(t2 != -1)
135                     tmp = min(tmp,key[t2] - key[root]);
136                 ans += tmp;
137             }
138         }
139         printf("%d\n",ans);
140     }
141     return 0;
142 }

 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3280079.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞