zoukankan      html  css  js  c++  java
  • HNOI200——营业额统计(splay/treap)

    Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:记该天以前某一天的营业额为 ai,该天营业额为 b,则该天的最小波动值 δ=min|ai−b|δ=min|ai−b|,当最小波动值越大时,就说明营业情况越不稳定。而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助 Tiger 来计算这一个值,第一天的最小波动值为第一天的营业额。
    一句话题意 给出一个 n个数的数列{an},对于第 i 个元素 ai,定义 fi=min|ai−aj|fi=min|ai−aj|,其中1≤j<i,f1=a1。求 ∑fi
    输入
    第一行为正整数,表示该公司从成立一直到现在的天数;接下来的 n 行每行有一个正整数,表示第 i 天公司的营业额 ai
    输出
    一个正整数,即每一天最小波动的和,结果不超过 2^31
    样例输入
    6512546
    样例输出
    12
    提示样例说明5+|1−5|+|2−1|+|5−5|+|4−5|+|6−5|=5+4+1+0+1+1=125+|1−5|+|2−1|+|5−5|+|4−5|+|6−5|=5+4+1+0+1+1=12
    对于全部数据,1≤n<2^15,
    ai≤10^6

    很简答的一道题吧。。。。。

    splay和treap都可以做

    结果tm有个点有负数然而读优没判

    卡到心态爆炸

    splay写法

    #include<bits/stdc++.h>
    using namespace std;
    int fa[50005],lc[50005],rc[50005],val[50005],cnt,n,root;
    inline int read()
    {
       int x=0,f=1;
       char c;
       for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
       if(c=='-') {f=-1;c=getchar();}
       for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
       return x*f;
    }
    inline int which(int x)
    {
     return rc[fa[x]]==x;
    }
    inline void add(int &x,int fat,int valu)
    {
     x=++cnt,fa[x]=fat,val[x]=valu;
    } 
    inline void rotate(int x)
    {
     int v=fa[x],z=fa[v];
     int b=x==rc[v]?lc[x]:rc[x];
     fa[x]=z,fa[v]=x;
     if(b) fa[b]=v;
     if(z) (lc[z]==v?lc[z]:rc[z])=x;
     if(x==lc[v]) rc[x]=v,lc[v]=b;
     else lc[x]=v,rc[v]=b;
    }
    inline void splay(int x)
    {
     while(fa[x])
     {
      if(fa[fa[x]])
      {
       if(which(x)==which(fa[x])) rotate(fa[x]);
       else rotate(x);
      }
      rotate(x);
     }
     root=x;
    }
    inline bool  insert(int v)
    {
     int u=root;
     while(v>val[u]?rc[u]:lc[u])
     {
      if(v==val[u]) {splay(u);return false;}
      u=v>val[u]?rc[u]:lc[u];
     }
     if(v==val[u]) {splay(u);return false;}
     add(v>val[u]?rc[u]:lc[u],u,v);
     splay(v>val[u]?rc[u]:lc[u]);
     return true;
    }
    inline int front(int u){
     int k=lc[u];
     if(k==0)  return -1e7;
     while(rc[k]) k=rc[k];
     return val[k];
    }
    inline int back(int u)
    {
     int k=rc[u];
     if(k==0) return -1e7;
     while(lc[k]) k=lc[k];
     return val[k];
    }
    int main(){
     n=read();
     int ans=0,x;
     for(int i=1;i<=n;i++)
     {
      x=read();
      if(i==1)
      {
       ans+=x; 
       add(root,0,x);
      }
      else
      {
       if(!insert(x)) continue;
       ans+=(min(abs(x-front(root)),abs(x-back(root))));
      }
     }
     cout<<ans<<endl;
     return 0;
    }
    

    treap写法

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
       int x=0,f=1;
       char c;
       for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
       if(c=='-') {f=-1;c=getchar();}
       for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
       return x*f;
    }
    int n,root=1,tot,ans;
    int lc[50105],rc[50105],data[50105],val[50105];
    const int inf =1e9+7;
    inline int add(int va)
    {
     val[++tot]=va;
     data[tot]=rand();
     return tot;
    }
    inline void build()
    {
     add(-inf);
     add(inf);
     rc[1]=2;
    }
    inline void zig(int &p)
    {
     int q=lc[p];
     lc[p]=rc[q],rc[q]=p,p=q;
    }
    inline void zag(int &p)
    {
     int q=rc[p];
     rc[p]=lc[q],lc[q]=p,p=q;
    }
    inline void insert(int &p,int va)
    {
     if(p==0)
     {
      p=add(va);
      return ;
     }
     if(va==val[p]) return ;
     if(va<val[p])
     {
      insert(lc[p],va);
      if(data[lc[p]]>data[p]) zig(p); 
     }
     else
     {
      insert(rc[p],va);
      if(data[rc[p]]>data[p]) zag(p);
     }
    }
    inline int pre(int va)
    {
     int cur=1,p=root;
     while(p)
     {
      if(val[p]==va) return va;
      if(val[p]<va&&val[p]>val[cur]) cur=p;
      p=val[p]>va?lc[p]:rc[p];
     }
     return val[cur];
    }
    inline int nxt(int va)
    {
     int cur=2,p=root;
     while(p)
     {
      if(val[p]==va)return va;
      if(val[p]>va&&val[p]<val[cur]) cur=p;
      p=val[p]>va?lc[p]:rc[p];
     }
     return val[cur];
    }
    int main(){
     srand(time(0));
     int ans=0,x;
     n=read();
     build();
     for(int i=1;i<=n;i++)
     {
      x=read();
      if(i==1)
      {
       ans+=x;
      }
      else
      {
       int a=pre(x),b=nxt(x);
       if(a==-inf&&b!=inf) ans+=b-x;
       if(a!=-inf&&b==inf) ans+=x-a;
       if(a!=-inf&&b!=inf) ans+=min((x-a),(b-x));
      }
      insert(root,x);
     }
     cout<<ans<<endl;
     return 0;
    }
    
  • 相关阅读:
    基础普及-Jar、War、Ear
    Guice 学习(五)多接口的实现( Many Interface Implementation)
    Foundation框架
    windowsclient开发--使用、屏蔽一些快捷键
    数据结构(Java语言)——BinaryHeap简单实现
    最小生成树之Prim(普里姆)算法
    LeetCode--Remove Element
    Java实现算法之--选择排序
    kvm云主机使用宿主机usb设备
    Oracle12c Client安装出现"[INS-30131]"错误“请确保当前用户具有访问临时位置所需的权限”解决办法之完整版
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366497.html
Copyright © 2011-2022 走看看