平衡树题,求每个点的前驱,照例可以用set水过。。。(平衡树还是不会写)
又新学了一个用法:
set <int> ::iterator s1;
这样s1就可以直接附为set中的地址了。但是调用值的时候要加一个*。
题干:
Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。 输入输出要求 Input 第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i 天公司的营业额。 天数n<=32767, 每天的营业额ai <= 1,000,000。 最后结果T<=2^31 Output 输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。 Sample Input 6 5 1 2 5 4 6 Simple Output 12 HINT 结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12 该题数据bug已修复.----2016.5.15
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<set> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } set <ll> s; set <ll> ::iterator s1; int n,p; ll ans = 0; int main() { read(n); if(n == 0) { printf("0 "); return 0; } read(p); s.insert(p); ans = p; duke(i,2,n) { read(p); s1 = s.lower_bound(p); ll minn = INF; if(s1 != s.end()) { minn = min(minn,abs(*s1 - p)); // cout<<t<<endl; } if(s1 != s.begin()) { minn = min(minn,abs(*--s1 - p)); // cout<<t<<endl; } ans += minn; s.insert(p); } write(ans); return 0; } /* 6 5 1 2 5 4 6 */