zoukankan      html  css  js  c++  java
  • p2234&bzoj1588 营业额统计

    传送门

    题目

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

    Input

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

    Output

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

    分析

    按天数顺序将每天权值依次加入线段树中权值所在位置,每一次波折即为在此点之前的最大值和此点的差与在此点之后的最小值与此点的差的最小值。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int inf=1e9+7;
    map<int,int>id;
    map<int,int>back;
    int d[3][440000],a[110000],b[110000];
    inline int read(){
          int x=0,f=1;char s=getchar();
          while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
          while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s-'0');s=getchar();}
          return f*x;
    }
    inline void add(int le,int ri,int k,int wh){
          d[0][wh]=max(d[0][wh],k),d[1][wh]=min(d[1][wh],k);
          if(le==ri)return;
          int mid=(le+ri)>>1;
          if(mid>=k)add(le,mid,k,wh*2);
            else add(mid+1,ri,k,wh*2+1);
    }
    inline int q(int le,int ri,int x,int y,int wh,int mm){
          if(mm==0){
              if(le>=x&&ri<=y)return d[0][wh];
              int ans=0,mid=(le+ri)>>1;
              if(mid>=x)ans=max(ans,q(le,mid,x,y,wh*2,mm));
              if(mid<y)ans=max(ans,q(mid+1,ri,x,y,wh*2+1,mm));
              return ans;
          }else {
              if(le>=x&&ri<=y)return d[1][wh];
              int ans=inf,mid=(le+ri)>>1;
              if(mid>=x)ans=min(ans,q(le,mid,x,y,wh*2,mm));
              if(mid<y)ans=min(ans,q(mid+1,ri,x,y,wh*2+1,mm));
              return ans;
          }
    }
    int main()
    {     int n,m,i,j,k,ans=0,sum=0;
          for(i=1;i<=400000;i++)d[1][i]=inf;
          n=read();
          for(i=1;i<=n;i++){
               a[i]=read();
               b[i]=a[i];
          }
          sort(b+1,b+n+1);
          for(i=1;i<=n;i++)
             if(!id[b[i]]){
                 id[b[i]]=++sum;
                 back[sum]=b[i];
             }
          ans+=a[1];
          add(1,sum,id[a[1]],1);
          for(i=2;i<=n;i++){
               int tot=inf,x=q(1,sum,1,id[a[i]],1,0),y=q(1,sum,id[a[i]],sum,1,1);
             if(x>0)tot=min(tot,abs(back[x]-a[i]));
             if(y<inf)tot=min(tot,abs(back[y]-a[i]));
             ans+=tot;
             add(1,sum,id[a[i]],1);
          }
          printf("%d
    ",ans);
          return 0;
    }
  • 相关阅读:
    java里的分支语句--程序运行流程的分类(顺序结构,分支结构,循环结构)
    Java里的构造函数(构造方法)
    Java里this的作用和用法
    JAVA中的重载和重写
    从键盘接收字符类型的数据并实现剪刀石头布的规则
    使用Notepad++编码编译时报错(已解决?)
    云就是网络,云计算呢
    使用JavaMail创建邮件和发送邮件
    mysql锁机制
    java中几种常用的设计模式
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9188783.html
Copyright © 2011-2022 走看看