bzoj1588
treap模版。。
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<ctime> 5 #include<cmath> 6 #include<iostream> 7 #include<algorithm> 8 #include<stack> 9 #define clr(a,x) memset(a,x,sizeof(a)) 10 #define rep(i,l,r) for(int i=l;i<r;i++) 11 using namespace std; 12 typedef long long ll; 13 const int maxn=50009,inf=0x3fffffff; 14 int n,m,x,ans=0; 15 struct treap{ 16 int root,size; 17 treap(){ 18 root=0;size=1; 19 } 20 struct node{ 21 int l,r,s,g,w,v; 22 }; 23 node x[maxn]; 24 inline void maintain(int k){ 25 x[k].s=x[x[k].l].s+x[x[k].r].s+x[k].g; 26 } 27 inline void lrot(int&k){ 28 int t=x[k].r; 29 x[k].r=x[t].l; 30 x[t].l=k; 31 x[t].s=x[k].s; 32 maintain(k); 33 k=t; 34 } 35 inline void rrot(int&k){ 36 int t=x[k].l; 37 x[k].l=x[t].r; 38 x[t].r=k; 39 x[t].s=x[k].s; 40 maintain(k); 41 k=t; 42 } 43 inline void insert(int&k,int a){ 44 if(!k){ 45 k=size; 46 x[size].v=a;x[size].s=x[size].g=1;x[size++].w=rand(); 47 return; 48 } 49 ++x[k].s; 50 if(a==x[k].v){ 51 ++x[k].g;return; 52 } 53 if(a>x[k].v){ 54 insert(x[k].r,a); 55 if(x[x[k].r].w>x[k].w) lrot(k); 56 return; 57 } 58 insert(x[k].l,a); 59 if(x[x[k].l].w>x[k].w) rrot(k); 60 } 61 inline void del(int&k,int a){ 62 if(!k) return; 63 if(x[k].v==a){ 64 if(x[k].g>1){ 65 --x[k].g;--x[k].s; 66 return; 67 } 68 if(x[k].l*x[k].r==0) k=x[k].l+x[k].r; 69 else if(x[x[k].l].w>x[x[k].r].w){ 70 rrot(k);del(k,a); 71 } 72 else{ 73 lrot(k);del(k,a); 74 } 75 return; 76 } 77 if(a>x[k].v) --x[k].s,del(x[k].r,a); 78 else --x[k].s,del(x[k].l,a); 79 } 80 inline int rank(int k,int a){ 81 if(!k) return 0; 82 if(x[k].v==a) return x[x[k].l].s+1; 83 if(a>x[k].v) return x[x[k].l].s+x[k].g+rank(x[k].r,a); 84 return rank(x[k].l,a); 85 } 86 inline int num(int k,int a){ 87 if(!k) return 0; 88 if(a<=x[x[k].l].s) return num(x[k].l,a); 89 if(a>x[x[k].l].s+x[k].g) return num(x[k].r,a-x[x[k].l].s-x[k].g); 90 return x[k].v; 91 } 92 inline int pre(int k,int a){ 93 if(!k) return -inf; 94 return x[k].v>a?pre(x[k].l,a):max(x[k].v,pre(x[k].r,a)); 95 } 96 inline int suc(int k,int a){ 97 if(!k) return inf; 98 return x[k].v<a?suc(x[k].r,a):min(x[k].v,suc(x[k].l,a)); 99 } 100 }; 101 treap T; 102 int main(){ 103 scanf("%d",&n); 104 rep(i,0,n){ 105 x=0; 106 scanf("%d",&x); 107 int g=T.pre(T.root,x),t=T.suc(T.root,x); 108 int f=min(g==-inf?inf:x-g,t==inf?x:t-x); 109 if(g==-inf&&t==inf) f=x; 110 ans+=f; 111 T.insert(T.root,x); 112 } 113 printf("%d\n",ans); 114 return 0; 115 }
1588: [HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 10991 Solved: 3861
[Submit][Status][Discuss]
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
此题数据有问题,详见讨论版http://www.lydsy.com/JudgeOnline/wttl/wttl.php?pid=1588