[HNOI2002]营业额统计
OJ题号:
BZOJ1588、洛谷3390
题目大意:
给定一个长度为n的数列a,求$\displaystyle{\sum_{i=1}^{n}\min_{1\leq j<i}}(|a_i-a_j|)$。
思路:
Splay。
每次插入后将当前结点splay到根结点,然后找出左子树中最大的数和右子树中最小的数,对root.val作差取min即可。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 char ch; 6 bool neg=false; 7 while(!isdigit(ch=getchar())) if(ch=='-') neg=true; 8 int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return neg?-x:x; 11 } 12 const int inf=0x7fffffff; 13 class SplayTree { 14 private: 15 struct Node { 16 int val; 17 Node *par,*left,*right; 18 Node(Node *const &p,const int v) { 19 par=p; 20 val=v; 21 left=right=NULL; 22 } 23 }; 24 void rotate_left(Node *p) { 25 Node *q=p->par; 26 q->right=p->left; 27 if(q->right) q->right->par=q; 28 p->left=q; 29 p->par=q->par; 30 q->par=p; 31 if(!p->par) { 32 root=p; 33 } else { 34 if(q==p->par->left) { 35 p->par->left=p; 36 } else { 37 p->par->right=p; 38 } 39 } 40 } 41 void rotate_right(Node *p) { 42 Node *q=p->par; 43 q->left=p->right; 44 if(q->left) q->left->par=q; 45 p->right=q; 46 p->par=q->par; 47 q->par=p; 48 if(!p->par) { 49 root=p; 50 } else { 51 if(q==p->par->left) { 52 p->par->left=p; 53 } else { 54 p->par->right=p; 55 } 56 } 57 } 58 void splay(Node *&p) { 59 if(!p->par) return; 60 if(p==p->par->left) { 61 rotate_right(p); 62 } else { 63 rotate_left(p); 64 } 65 } 66 int find_left(Node *const &p) { 67 if(!p) return inf; 68 int t=find_left(p->left); 69 return t!=inf?t:p->val; 70 } 71 int find_right(Node *const &p) { 72 if(!p) return inf; 73 int t=find_right(p->right); 74 return t!=inf?t:p->val; 75 } 76 public: 77 Node *root; 78 void insert(Node *&p,Node *const &par,const int &v) { 79 if(!p) { 80 p=new Node(par,v); 81 splay(p); 82 return; 83 } 84 if(v<=p->val) { 85 insert(p->left,p,v); 86 } else { 87 insert(p->right,p,v); 88 } 89 splay(p); 90 } 91 int query() { 92 int ret=inf; 93 if(root->left) { 94 ret=std::min(ret,root->val-find_right(root->left)); 95 } 96 if(root->right) { 97 ret=std::min(ret,find_left(root->right)-root->val); 98 } 99 return ret; 100 } 101 }; 102 SplayTree t; 103 int main() { 104 int n=getint(),ans=0; 105 for(int i=1;i<=n;i++) { 106 int x=getint(); 107 t.insert(t.root,NULL,x); 108 ans+=i==1?x:t.query(); 109 } 110 printf("%d\n",ans); 111 return 0; 112 }