bzoj1588 [HNOI2002]营业额统计
Description
营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业 额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了 一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。 输入输出要求
Input
第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i天公司的营业额。
Output
输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。
Sample Input
6
5
1
2
5
4
6
5
1
2
5
4
6
Sample 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
正解:平衡树。
以前就用splay码过,今天学了SBT,于是又写了一下。然而发现对于这道题,splay似乎还快些。。
splay:
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <stack> 11 #include <set> 12 #include <map> 13 #define inf (1<<30) 14 #define N (100010) 15 #define il inline 16 #define RG register 17 #define ll long long 18 19 using namespace std; 20 21 int ch[N][2],pre[N],key[N],n,tot,root; 22 ll ans; 23 24 il int gi(){ 25 RG int x=0,q=0; RG char ch=getchar(); 26 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=1,ch=getchar(); 27 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q ? -x : x; 28 } 29 30 il void newnode(RG int &x,RG int fa,RG int keyy){ x=++tot,pre[x]=fa,key[x]=keyy,ch[x][0]=ch[x][1]=0; return; } 31 32 il void rotate(RG int x,RG int kind){ 33 RG int p=pre[x]; ch[p][!kind]=ch[x][kind],pre[ch[x][kind]]=p; 34 ch[pre[p]][ch[pre[p]][1]==p]=x,pre[x]=pre[p]; 35 ch[x][kind]=p,pre[p]=x; return; 36 } 37 38 il void splay(RG int x,RG int goal){ 39 while (pre[x]!=goal){ 40 if (pre[pre[x]]==goal) rotate(x,ch[pre[x]][0]==x); else{ 41 RG int p=pre[x],kind=(ch[pre[p]][0]==p); 42 if (ch[p][kind]==x) rotate(x,!kind),rotate(x,kind); 43 else rotate(p,kind),rotate(x,kind); 44 } 45 } 46 if (goal==0) root=x; return; 47 } 48 49 il int insert(RG int keyy){ 50 while (ch[root][key[root]<keyy]){ 51 if (key[root]==keyy){ splay(root,0); return 0; } 52 root=ch[root][key[root]<keyy]; 53 } 54 newnode(ch[root][key[root]<keyy],root,keyy),splay(ch[root][key[root]<keyy],0); return 1; 55 } 56 57 il int get_pre(RG int x){ 58 RG int tmp=ch[x][0]; if (!tmp) return inf; 59 while (ch[tmp][1]) tmp=ch[tmp][1]; return key[tmp]; 60 } 61 62 il int get_next(RG int x){ 63 RG int tmp=ch[x][1]; if (!tmp) return inf; 64 while (ch[tmp][0]) tmp=ch[tmp][0]; return key[tmp]; 65 } 66 67 il void work(){ 68 n=gi(),ans=gi(); newnode(root,0,ans); 69 for (RG int i=2;i<=n;++i){ 70 RG int num=0; scanf("%d",&num); 71 if (insert(num)==0) continue; 72 RG int pr=get_pre(root),nt=get_next(root); 73 ans+=min(abs(key[root]-pr),abs(nt-key[root])); 74 } 75 printf("%lld\n",ans); return; 76 } 77 78 int main(){ 79 work(); 80 return 0; 81 }
SBT:
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define inf (1<<30) 15 #define N (100010) 16 #define il inline 17 #define RG register 18 #define ll long long 19 20 using namespace std; 21 22 int ch[N][2],key[N],s[N],n,w,rt,tot; 23 ll ans; 24 25 il int gi(){ 26 RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 27 if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; 28 } 29 30 il void rotate(RG int &x,RG int k){ 31 RG int y=ch[x][k^1]; ch[x][k^1]=ch[y][k],ch[y][k]=x; 32 s[y]=s[x],s[x]=s[ch[x][0]]+s[ch[x][1]]+1,x=y; 33 return; 34 } 35 36 il void maintain(RG int &x,RG int k){ 37 if (s[ch[ch[x][k^1]][k^1]]>s[ch[x][k]]) rotate(x,k); 38 else if (s[ch[ch[x][k^1]][k]]>s[ch[x][k]]) rotate(ch[x][k^1],k^1),rotate(x,k); 39 else return; 40 maintain(ch[x][0],1),maintain(ch[x][1],0); 41 maintain(x,1),maintain(x,0); return; 42 } 43 44 il void insert(RG int &x,RG int k,RG int &w){ 45 if (!x){ x=k; return; } 46 s[x]++,w=min(w,abs(key[x]-key[k])); 47 if (key[x]>key[k]) insert(ch[x][0],k,w); 48 else insert(ch[x][1],k,w); 49 maintain(x,key[x]>key[k]); return; 50 } 51 52 il void work(){ 53 n=gi(),ans=gi(),key[tot=rt=1]=ans,s[tot]=1; 54 for (RG int i=2;i<=n;++i){ 55 RG int j=0; scanf("%d",&j); 56 key[++tot]=j,s[tot]=1; 57 w=inf,insert(rt,tot,w),ans+=w; 58 } 59 printf("%lld\n",ans); return; 60 } 61 62 int main(){ 63 work(); 64 return 0; 65 }