[HNOI2002]营业额统计(Splay模板)
本来一直嫌麻烦只写spaly,结果被模板题卡T了,只能写正版splay,然后发现原来挺好写的,而且快了好多QwQ。
思路:每次对ai统计“最小波动值”的时候有两种情况,aj>=ai和aj<ai,取差值最小的一种。就是ai的前驱和后继,可以用splay维护和查找。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 6 struct SplayNode { 7 SplayNode *fa, *son[2]; 8 int weight; 9 SplayNode(SplayNode *f = NULL, int w = 0):fa(f), weight(w) { 10 son[0] = son[1] = NULL; 11 } 12 }*root = NULL; 13 14 void rotate(SplayNode*); 15 void Splay(SplayNode*); 16 SplayNode *insert(int); 17 SplayNode *findPredecessor(SplayNode*); 18 SplayNode *findSuccessor(SplayNode*); 19 20 int main() { 21 int n, ans = 0; 22 scanf("%d", &n); 23 for (int i = 0; i < n; i++) { 24 int d; 25 scanf("%d", &d); 26 if (!root) { 27 ans = d; 28 root = new SplayNode(NULL, d); 29 } 30 else { 31 SplayNode *p = insert(d); 32 int min_d = 0x3f3f3f3f; 33 SplayNode *l = findPredecessor(p), *r = findSuccessor(p); 34 if (l) min_d = p->weight - l->weight; 35 if (r) min_d = min(min_d, r->weight - p->weight); 36 ans += min_d; 37 //printf("%d\n", min_d); 38 } 39 } 40 printf("%d\n", ans); 41 return 0; 42 } 43 44 void rotate(SplayNode *rt) { 45 int d = (rt->fa->son[0] == rt); 46 SplayNode *f = rt->fa, *s = rt->son[d]; 47 f->son[d ^ 1] = s; 48 if (s) s->fa = f; 49 rt->son[d] = f; 50 if (f->fa) f->fa->son[f->fa->son[1] == f] = rt; 51 rt->fa = f->fa; 52 f->fa = rt; 53 } 54 55 void Splay(SplayNode *rt) { 56 while(rt->fa) { 57 if (!rt->fa->fa) rotate(rt); 58 else { 59 int d1 = (rt->fa->son[1] == rt), d2 = (rt->fa->fa->son[1] == rt->fa); 60 if (d1 == d2) { 61 rotate(rt->fa); 62 rotate(rt); 63 } else { 64 rotate(rt); 65 rotate(rt); 66 } 67 } 68 } 69 root = rt; 70 } 71 72 SplayNode *insert(int w) { 73 SplayNode *p = root; 74 while (1) { 75 int d = (w > p->weight); 76 if (!p->son[d]) 77 return p->son[d] = new SplayNode(p, w); 78 p = p->son[d]; 79 } 80 } 81 82 SplayNode *findPredecessor(SplayNode *rt) { 83 Splay(rt); 84 if (!rt->son[0]) return NULL; 85 SplayNode *p = rt->son[0]; 86 while (p->son[1]) p = p->son[1]; 87 return p; 88 } 89 90 SplayNode *findSuccessor(SplayNode *rt) { 91 Splay(rt); 92 if (!rt->son[1]) return NULL; 93 SplayNode *p = rt->son[1]; 94 while (p->son[0]) p = p->son[0]; 95 return p; 96 }