题目描述
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:

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

当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。
输入
第一行为正整数n(n≤32767),表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数ai(ai≤1000000),表示第i天公司的营业额。
输出
仅有一个正整数,即 ∑每一天的最小波动值。结果小于231
样例输入
6
5
1
2
5
4
6
样例输出
12
提示
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
Treap
前驱可以和自己相等,就是相同的数可以有不同的排名
就简单了好多

#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int N=1e5+10; struct Treap{ int l,r; int val,dat;}a[N]; int tot,root,n; int New(int val) { a[++tot].val=val; a[tot].dat=rand(); return tot; } void build() { New(-inf); New(inf); root=1; a[1].r=2; } void zig(int &p) { int q=a[p].l; a[p].l=a[q].r; a[q].r=p; p=q; } void zag(int &p) { int q=a[p].r; a[p].r=a[q].l; a[q].l=p; p=q; } void Insert(int &p,int val) { if (p==0) { p=New(val); return ; } if (val<a[p].val) { Insert(a[p].l,val); if (a[p].dat<a[a[p].l].dat) zig(p); } else { Insert(a[p].r,val); if (a[p].dat<a[a[p].r].dat) zag(p); } } int GetPre(int val) { int ans=1; int p=root; while (p) { if (val>=a[p].val) ans=p,p=a[p].r; else p=a[p].l; } return a[ans].val; } int GetNext(int val) { int ans=2; int p=root; while (p) { if (val<=a[p].val) ans=p,p=a[p].l; else p=a[p].r; } return a[ans].val; } int main() { build(); scanf("%d",&n); int x,ans=0; for (int i=1;i<=n;i++) { scanf("%d",&x); if (i==1) ans+=x; else { int pre=GetPre(x); int nex=GetNext(x); ans+=min(x-pre,nex-x); } Insert(root,x); } printf("%d ",ans); return 0; }
双向链表
留坑qwq