• 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;
    }
  • 相关阅读:
    Lucene的分页查询
    Lucene索引库的简单优化
    Lucene的排序搜索
    Axure RP 6.5学习记录(1)界面介绍
    Lucene的高亮器Highlighter
    关于Lucene以及索引和搜索的流程
    Lucene初体验
    linux 下 ansi_x3.41968 java 邮件附件乱码
    SQL Server DBA工作内容详解
    SQL Server 导出 insert into 脚本
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9188783.html
Copyright © 2020-2023  润新知