BZOJ1588 [HNOI2002]营业额统计

裸splay,最近刚学了一下。下面是一篇关于学splay的很不错的文章

http://wenku.baidu.com/view/a202e27931b765ce05081416.html

现在只看到了插入操作。到目前为止发现了这篇文章两个错误的地方

第一个是在splay函数里的22行,应该是左旋

第二个是在插入函数里的28行应该是对tot(也就是当前节点)进行伸展操作

 

对于这道题,每读入一个数,插入进去之后,在其左子树里查找最大值,在右子树里查找最小值,即当前值相差最小的两个节点。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 40005;
 7 const int INF = 0x3f3f3f3f;
 8 int fa[maxn],son[2][maxn],val[maxn];
 9 int root,tot;
10 void rota(int w,int x){
11     int y = fa[x];
12     son[!w][y] = son[w][x];
13     if(son[w][x])fa[son[w][x]] = y;
14     fa[x] = fa[y];
15     if(fa[y])son[y==son[1][fa[y]]][fa[y]] = x;
16     son[w][x] = y;fa[y] = x;
17 }
18 void splay(int x,int y){
19     while(fa[x]!=y){
20         if(fa[fa[x]]==y)rota(x==son[0][fa[x]],x);
21         else {
22             int w = fa[x]==son[0][fa[fa[x]]];
23             if(x==son[w][fa[x]]){
24                 rota(!w,x);
25                 rota(w,x);
26             }
27             else {
28                 rota(w,fa[x]);
29                 rota(w,x);
30             }
31         }
32     }
33     if(!y)root = x;
34 }
35 int insert(int v){
36     int x = root;
37     while(1){
38         if(v==val[x]){splay(x,0);return 0;}
39         if(v<val[x]){
40             if(son[0][x])x = son[0][x];
41             else break;
42         }
43         else {
44             if(son[1][x])x = son[1][x];
45             else break;
46         }
47     }
48     fa[++tot] = x;
49     val[tot] = v;
50     if(v<val[x])son[0][x] = tot;
51     else son[1][x] = tot;
52     splay(tot,0);
53     return 1;
54 }
55 int getfa(){
56     int x =son[0][root];
57     if(x==0)return INF;
58     while(son[1][x])x = son[1][x];
59     return val[x];
60 }
61 int getson(){
62     int x = son[1][root];
63     if(x==0)return INF;
64     while(son[0][x])x = son[0][x];
65     return val[x];
66 }
67 int main()
68 {
69     int ans = 0,n;scanf("%d",&n);
70     for(int i = 1;i<=n;++i){
71         int t;if(scanf("%d",&t)==EOF)t = 0;
72         if(i==1){
73             root = ++tot;
74             val[tot] = t;
75             ans+=t;
76             continue;
77         }
78         if(insert(t)==0)continue;
79         int a = getfa(),b = getson();
80         ans+=min(abs(a-t),abs(b-t));
81     }
82     printf("%d\n",ans);
83     return 0;
84 }

 

posted on 2015-08-04 22:44  round_0  阅读(154)  评论(0编辑  收藏  举报

导航