zoukankan      html  css  js  c++  java
  • [BZOJ1588] [HNOI2002] 营业额统计 (treap)

    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

    Solution

      嘛,有一个测试点少了一个零。

      这道题用treap找前驱后继,比较哪个数和给定的数的差值小,再把这个数插入treap里。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct treap
     4 {
     5     int key, val, l, r, pri, siz;
     6 }a[50005];
     7 int root, ptot, p, s;
     8  
     9 void push_up(int k)
    10 {
    11     a[k].siz = a[a[k].l].siz + a[a[k].r].siz + 1;
    12 }
    13  
    14 void lturn(int &k)
    15 {
    16     int tmp = a[k].r;
    17     a[k].r = a[tmp].l, a[tmp].l = k;
    18     a[tmp].siz = a[k].siz, push_up(k), k = tmp;
    19 }
    20  
    21 void rturn(int &k)
    22 {
    23     int tmp = a[k].l;
    24     a[k].l = a[tmp].r, a[tmp].r = k;
    25     a[tmp].siz = a[k].siz, push_up(k), k = tmp;
    26 }
    27  
    28 void insert(int &k, int x)
    29 {
    30     if(!k)
    31     {
    32         k = ++ptot, a[k].key = x, a[k].pri = rand();
    33         a[k].siz = a[k].val = 1;
    34         return;
    35     }
    36     a[k].siz++;
    37     if(a[k].key == x) a[k].val++;
    38     else if(x < a[k].key)
    39     {
    40         insert(a[k].l, x);
    41         if(a[k].pri < a[a[k].l].pri) rturn(k);
    42     }
    43     else
    44     {
    45         insert(a[k].r, x);
    46         if(a[k].pri < a[a[k].r].pri) lturn(k);
    47     }
    48 }
    49  
    50 void query_pro(int k, int x)
    51 {
    52     if(!k) return;
    53     if(x < a[k].key) query_pro(a[k].l, x);
    54     else p = a[k].key, query_pro(a[k].r, x);
    55 }
    56  
    57 void query_sub(int k, int x)
    58 {
    59     if(!k) return;
    60     if(x > a[k].key) query_sub(a[k].r, x);
    61     else s = a[k].key, query_sub(a[k].l, x);
    62 }
    63  
    64 int main()
    65 {
    66     int n, x, ans;
    67     scanf("%d", &n), srand(n);
    68     for(int i = 1; i <= n; i++)
    69     {
    70         if(!~scanf("%d", &x)) x = 0;
    71         if(i == 1) ans = x;
    72         else
    73         {
    74             p = -1000000000, query_pro(root, x);
    75             s = 1000000000, query_sub(root, x);
    76             ans += min(x - p, s - x);
    77         }
    78         insert(root, x);
    79     }
    80     printf("%d
    ", ans);
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    C++输入问题探究
    剑指offer自学系列(一)
    一道算法题加深我对C++中map函数的理解
    数据结构和算法自学之排序算法(一)
    pyqt5_01_流程走通
    最新谷歌驱动对照表
    移动端测试
    selenium封装
    request封装
    MD5自定义加密
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5356617.html
Copyright © 2011-2022 走看看