[luogu P2234] [HNOI2002]营业额统计
题目描述
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:
当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。
该天的最小波动值=min{|该天以前某一天的营业额-该天营业额|}。
输入输出格式
输入格式:
输入由文件’turnover.in’读入。
第一行为正整数n(n<=32767) ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数ai(|ai|<=1000000) ,表示第i天公司的营业额,可能存在负数。
输出格式:

输入输出样例
说明
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
一起用splay做这道题,现在再用treap写,感觉完全不一样。。。
treap真是个好东西。。。(但splay当然也有其优点)
这道题就是找一下前驱后继罢了。
code:


1 %:pragma GCC optimize(2) 2 #include<bits/stdc++.h> 3 #define Ms(a,x) memset(a,x,sizeof a) 4 using namespace std; 5 const int N=32768; 6 int n,m,root,ans,final; 7 class treap{ 8 private: 9 int ch[N][2],v[N],k[N],s[N]; 10 public: 11 treap() {Ms(ch,0);} 12 inline void newnode(int &cur,int x) { 13 cur=++n,v[cur]=x,s[cur]=1,k[cur]=rand(); 14 } 15 inline void update(int cur) { 16 s[cur]=s[ch[cur][0]]+s[ch[cur][1]]+1; 17 } 18 inline void rotate(int &cur,int dir) { 19 int tmp=ch[ch[cur][dir^1]][dir]; 20 ch[ch[cur][dir^1]][dir]=cur; 21 cur=ch[cur][dir^1]; 22 ch[ch[cur][dir]][dir^1]=tmp; 23 update(ch[cur][dir]),update(cur); 24 } 25 inline void insert(int &cur,int x) { 26 if (!cur) {newnode(cur,x); return;} 27 if (v[cur]==x) {s[cur]++; return;} 28 bool q=v[cur]<x; 29 insert(ch[cur][q],x); 30 if (k[cur]>k[ch[cur][q]]) rotate(cur,q^1); else update(cur); 31 } 32 inline void x_pre(int cur,int x) { 33 if (!cur) return; 34 if (v[cur]>x) x_pre(ch[cur][0],x); 35 else ans=v[cur],x_pre(ch[cur][1],x); 36 } 37 inline void x_suc(int cur,int x) { 38 if (!cur) return; 39 if (v[cur]<x) x_suc(ch[cur][1],x); 40 else ans=v[cur],x_suc(ch[cur][0],x); 41 } 42 }t; 43 inline int read() { 44 int x=0,f=1; char ch=getchar(); 45 while (ch<'0'||ch>'9') f=(ch=='-')?-1:1,ch=getchar(); 46 while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); 47 return x*f; 48 } 49 int main() { 50 srand(520),root=final=n=0,m=read(); 51 for (int i=1,x,u,v,get; i<=m; i++) { 52 x=read(); 53 if (i==1) get=x; else { 54 ans=-1e9,t.x_pre(root,x),get=x-ans; 55 ans=1e9,t.x_suc(root,x),get=min(get,ans-x); 56 } 57 final+=get,t.insert(root,x); 58 } 59 return cout<<final<<endl,0; 60 }
本文介绍了一道经典算法题“营业额统计”,使用Treap数据结构解决最小波动值的计算问题,通过查找前驱和后继节点实现高效更新。
554

被折叠的 条评论
为什么被折叠?



