【Treap】BZOJ1588-[HNOI2002]营业额统计

【题目大意】
[借用别人的概括]给出一个n个数的数列a,对于第i个元素ai定义fi=min(abs(ai-aj)),(1<=j<i),其中f1=a1。输出sum(fi) (1<=i<=n)
【思路】
平衡树,易知绝对值最小的一定是前缀和后继。要注意的是由于ai和aj可能相等,即min可能等于零,要加一个判断:如果当前平衡树中的key等于要找的值,并且当前结点的cnt大于一个,则说明之前有一个值和当前相等。另外有些情况下当前要找的结点可能没有前驱或者后继,需要判断一下。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 const int INF=0x7fffffff;
  8 struct treap
  9 {
 10     int key;
 11     int priority;
 12     treap* lson;
 13     treap* rson;
 14     int cnt;
 15     treap()
 16     {
 17         key=0;
 18         cnt=1;
 19         /*这里初始值为1*/
 20         priority=rand();
 21         lson=rson=NULL;
 22     }
 23 };
 24 treap* root=NULL; 
 25  
 26 void RightRotate(treap* &rt)
 27 {
 28     treap* tmp=rt->lson;
 29     rt->lson=tmp->rson;
 30     tmp->rson=rt;
 31     rt=tmp;
 32 }
 33  
 34 void LeftRotate(treap* &rt)
 35 {
 36     treap *tmp=rt->rson;
 37     rt->rson=tmp->lson;
 38     tmp->lson=rt;
 39     rt=tmp;
 40 }
 41  
 42 void insert(treap* &rt,int x)
 43 {
 44     if (rt==NULL)
 45     {
 46         rt=new treap;
 47         rt->key=x;
 48     }
 49     else
 50     {
 51         if (rt->key==x)
 52         {
 53             rt->cnt++;
 54         }
 55         else if (rt->key>x)
 56         {
 57             insert(rt->lson,x);
 58             if (rt->lson->priority>rt->priority) RightRotate(rt);
 59         }
 60         else
 61         {
 62             insert(rt->rson,x);
 63             if (rt->rson->priority>rt->priority) LeftRotate(rt);
 64         }
 65     } 
 66 }
 67  
 68 int pre(treap* &rt,int x)
 69 {
 70     int ans=-INF;
 71     treap* tmp=rt;
 72     while (tmp)
 73     {
 74         if (tmp->key==x && tmp->cnt>1) return x; //【Attention】这句话非常重要,千万不要漏掉了! 
 75         if (tmp->key<x)
 76         {
 77             ans=max(tmp->key,ans);
 78             tmp=tmp->rson;
 79         } 
 80         else tmp=tmp->lson;
 81     }
 82     return ans;
 83 }
 84  
 85 int suc(treap* &rt,int x)
 86 {
 87     int ans=INF;
 88     treap *tmp=rt;
 89     while (tmp)
 90     {
 91         if (tmp->key>x)
 92         {
 93             if (tmp->key==x && tmp->cnt>1) return x; 
 94             ans=min(tmp->key,ans);//这里手滑写成了max(x,ans)orz 
 95             tmp=tmp->lson;
 96         }
 97         else tmp=tmp->rson;
 98     }
 99     return ans;
100 }
101  
102 int result()
103 {
104     int n,ans;
105     if(scanf("%d",&n) == EOF) n = 0;
106     for (int i=0;i<n;i++)
107     {
108         int turnover;
109         if(scanf("%d",&turnover) == EOF) turnover = 0;
110         insert(root,turnover);
111         if (i==0)
112         {
113             ans=turnover;
114         }
115         else
116         {
117             int premax,sucmin,ad=INF;
118             premax=pre(root,turnover);
119             sucmin=suc(root,turnover);
120             if (premax!=-INF && premax!=INF) ad=min(ad,turnover-premax);
121             if (sucmin!=INF && sucmin!=-INF) ad=min(ad,sucmin-turnover);
122             if (ad!=INF && ad!=-INF) ans=ans+ad;
123         }
124     }
125     return ans;
126 } 
127  
128 int main()
129 {
130     printf("%d",result());
131     return 0;
132 } 

 

posted @ 2016-03-26 19:51  iiyiyi  阅读(171)  评论(0编辑  收藏  举报