BZOJ 1588 [HNOI2002]营业额统计
1588: [HNOI2002]营业额统计
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
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
这是一道裸题,BST。可以用TREAP,十分经典。不多说了。(LMY给我们一个小时做)
1 /************************************************************** 2 Problem: 1588 3 User: Doggu 4 Language: C++ 5 Result: Accepted 6 Time:192 ms 7 Memory:1448 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 const int N = 40000; 14 struct Node { 15 int key, rd; 16 Node *ch[2]; 17 int cmp(int x) { 18 if(x==key) return -1; 19 return x>key; 20 } 21 }pool[N], *tail=pool, *root=pool, *null=pool; 22 int rand() { 23 static int seed=1000007; 24 return seed=(int)seed*48271LL%2147483647; 25 } 26 Node* newnode(int x) { 27 Node *nd = tail++; 28 nd->ch[0]=nd->ch[1]=null; 29 nd->key=x;nd->rd=rand(); 30 return nd; 31 } 32 void rotate(Node *&nd,int d) {//d=0 right(1) to left(0) d=1 left(0) to right(1) 33 Node *k=nd->ch[d^1];nd->ch[d^1]=k->ch[d];k->ch[d]=nd;nd=k; 34 } 35 int temp; 36 void query(Node *nd,int x) { 37 if(nd==null) temp=std::min(temp,x); 38 int d=nd->cmp(x); 39 temp=std::min(temp,std::abs(nd->key-x)); 40 if(d==-1||nd->ch[d]==null) return ; 41 query(nd->ch[d],x); 42 } 43 void insert(Node *&nd,int x) { 44 if(nd==null) nd=newnode(x); 45 else { 46 int d=nd->cmp(x); 47 if(d==-1) return ; 48 insert(nd->ch[d],x); 49 if(nd->ch[d]->rd>nd->rd) rotate(nd,d^1); 50 } 51 } 52 int main() { 53 null=newnode(0); 54 int n, x, ans = 0; 55 scanf("%d",&n); 56 for( int i = 1; i <= n; i++ ) { 57 scanf("%d",&x); 58 temp=0x3f3f3f3f;query(root,x);ans+=temp; 59 insert(root,x); 60 } 61 printf("%d",ans); 62 return 0; 63 } 64
再说一下,用SBT也可以,长度相似,但会慢一些。
1 /************************************************************** 2 Problem: 1588 3 User: Doggu 4 Language: C++ 5 Result: Accepted 6 Time:208 ms 7 Memory:1448 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 const int N = 40000; 14 struct Node { 15 int key, size; 16 Node *ch[2]; 17 int cmp(int x) { 18 if(x==key) return -1; 19 return x>key; 20 } 21 void update() {size = ch[0]->size + ch[1]->size + 1;} 22 }pool[N], *tail=pool, *root=pool, *null=pool; 23 Node* newnode(int x) { 24 Node *nd = tail++; 25 nd->key=x;nd->size=0; 26 nd->ch[0]=nd->ch[1]=null; 27 return nd; 28 } 29 void rotate(Node *&nd,int d) { 30 Node *k=nd->ch[d^1];nd->ch[d^1]=k->ch[d];k->ch[d]=nd; 31 nd->update();k->update();nd=k; 32 } 33 int temp; 34 void query(Node *nd,int x) { 35 if(nd==null) temp=std::min(temp,x); 36 int d=nd->cmp(x); 37 temp=std::min(temp,std::abs(nd->key-x)); 38 if(d==-1||nd->ch[d]==null) return ; 39 query(nd->ch[d],x); 40 } 41 void insert(Node *&nd,int x) { 42 if(nd==null) nd=newnode(x); 43 else { 44 int d=nd->cmp(x); 45 if(d==-1) return ; 46 insert(nd->ch[d],x); 47 nd->update(); 48 while(nd->ch[d]->size>nd->ch[d^1]->size) rotate(nd,d^1); 49 } 50 } 51 int main() { 52 null=newnode(0); 53 int n, x, ans = 0; 54 scanf("%d",&n); 55 for( int i = 1; i <= n; i++ ) { 56 scanf("%d",&x); 57 temp=0x3f3f3f3f;query(root,x);ans+=temp; 58 insert(root,x); 59 } 60 printf("%d",ans); 61 return 0; 62 } 63