【bzoj1588 营业额统计】
题目大意:
营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。
输入输出要求:
第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数 ,表示第i天公司的营业额。
输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。
样例输入:
6
5
1
2
5
4
6
样例输出:
12
题解:
splay第一题模板真的很丑,为了把所有操作写清楚,代码以后还会去优化。
用splay维护每次加入一个数,把第一个比它大或者小的数取出来。每次把这个数splay到root位置,然后把根节点leftson的子树中最右与rightson的子树中最左的节点取出来比较。如果在insert时有一样的数就可以直接return.(之前有出现这个数对答案贡献为0)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 using namespace std; 6 int cnt,root,ans,fl; 7 struct node 8 { 9 int fa,l,r,sum; 10 } tr[100005]; 11 inline void leftrotate(int x) 12 { 13 int y=tr[x].fa;int z=tr[y].fa; 14 tr[y].r=tr[x].l; 15 if(tr[x].l!=-1) tr[tr[x].l].fa=y; 16 tr[x].fa=z; 17 if(z!=-1) 18 { 19 if(tr[z].l==y) tr[z].l=x; 20 else tr[z].r=x; 21 } 22 tr[x].l=y;tr[y].fa=x; 23 } 24 inline void rightrotate(int x) 25 { 26 int y=tr[x].fa;int z=tr[y].fa; 27 tr[y].l=tr[x].r; 28 if(tr[x].r!=-1) tr[tr[x].r].fa=y; 29 tr[x].fa=z; 30 if(z!=-1) 31 { 32 if(tr[z].l==y) tr[z].l=x; 33 else tr[z].r=x; 34 } 35 tr[x].r=y;tr[y].fa=x; 36 } 37 inline void splay(int x) 38 { 39 while(tr[x].fa!=-1) 40 { 41 int y=tr[x].fa;int z=tr[y].fa; 42 if(z==-1) 43 { 44 if(tr[y].l==x) rightrotate(x); 45 else leftrotate(x); 46 } 47 else 48 { 49 if(tr[z].l==y && tr[y].l==x) 50 { 51 rightrotate(y); 52 rightrotate(x); 53 } 54 else if(tr[z].l==y && tr[y].r==x) 55 { 56 leftrotate(x); 57 rightrotate(x); 58 } 59 else if(tr[z].r==y && tr[y].l==x) 60 { 61 rightrotate(x); 62 leftrotate(x); 63 } 64 else 65 { 66 leftrotate(y); 67 leftrotate(x); 68 } 69 } 70 } 71 root=x; 72 } 73 inline int ls(int x) 74 { 75 int y=tr[x].l; 76 if(y==-1) return y; 77 while(tr[y].r!=-1) y=tr[y].r; 78 return y; 79 } 80 inline int nx(int x) 81 { 82 int y=tr[x].r; 83 if(y==-1) return y; 84 while(tr[y].l!=-1) y=tr[y].l; 85 return y; 86 } 87 inline void search(int x,int now) 88 { 89 if(x==tr[now].sum) 90 { 91 fl=0; 92 return; 93 } 94 if(x<tr[now].sum) 95 { 96 if(tr[now].l==-1) 97 { 98 tr[now].l=cnt,tr[cnt].fa=now,tr[cnt].l=tr[cnt].r=-1; 99 tr[cnt].sum=x; 100 } 101 else search(x,tr[now].l); 102 } 103 else 104 { 105 if(tr[now].r==-1) 106 { 107 tr[now].r=cnt,tr[cnt].fa=now,tr[cnt].l=tr[cnt].r=-1; 108 tr[cnt].sum=x; 109 } 110 else search(x,tr[now].r); 111 } 112 } 113 inline void insert(int x) 114 { 115 fl=1;cnt++; 116 search(x,root); 117 if(!fl) return; 118 splay(cnt); 119 int last=ls(cnt),next=nx(cnt); 120 int minn=1e9+7; 121 if(last!=-1) minn=min(minn,abs(tr[last].sum-x)); 122 if(next!=-1) minn=min(minn,abs(tr[next].sum-x)); 123 ans+=minn; 124 } 125 int main() 126 { 127 int n,x; 128 while(scanf("%d",&n)!=-1) 129 { 130 cnt=0; 131 scanf("%d",&x); 132 ans=x;tr[++cnt].fa=-1; 133 tr[cnt].sum=x; 134 root=cnt; 135 tr[cnt].l=tr[cnt].r=-1; 136 for(int i=1;i<n;i++) 137 { 138 scanf("%d",&x); 139 insert(x); 140 } 141 printf("%d",ans); 142 } 143 return 0; 144 }