您的位置:首页 > 其它

bzoj1588: [HNOI2002]营业额统计 splay瞎写

2017-01-16 20:47 204 查看
最近各种瞎写数论题,感觉需要回顾一下数据结构

写一发splay冷静一下(手速过慢,以后要多练练)

用splay是最直接的方法,但我感觉离散一波应该可以做出来(没仔细想过)

现在没有很追求代码优美,感觉得先打的对打的快O(∩_∩)O

1 #include <bits/stdc++.h>
2 #define INF 1000000000
3 using namespace std;
4 int root,N,n,x;
5 int fa[100005],c[100005][2],a[100005];
6 void rot(int x)
7 {
8     int fat=fa[x],k=c[fat][1]==x;
9     c[fat][k]=c[x][!k];fa[c[x][!k]]=fat;
10     fa[x]=fa[fat];c[fa[fat]][c[fa[fat]][1]==fat]=x;
11     fa[fat]=x;c[x][!k]=fat;
12 }
13 void splay(int x,int g)
14 {
15     for(int y;(y=fa[x])!=g;rot(x))
16     if(fa[y]!=g)
17     if((c[y][1]==x)==(c[fa[y]][1]==y)) rot(y);else rot(x);
18     if(g==0) root=x;
19 }
20 int lower(int p)
21 {
22     if(!root) return 0;
23     int ans=INF;
24     for(int i=root;i;(p>=a[i])?i=c[i][1]:i=c[i][0])
25     if(a[i]>=p)
26         ans=min(ans,a[i]);
27     return ans-p;
28 }
29 int upper(int p)
30 {
31     if(!root) return 0;
32     int ans=-INF;
33     for(int i=root;i;(p>=a[i])?i=c[i][1]:i=c[i][0])
34     if(a[i]<=p)
35         ans=max(ans,a[i]);
36     return p-ans;
37 }
38 void add(int x)
39 {
40     a[++N]=x;c
[0]=c
[1]=0;
41     if(!root)
42     {
43         root=N;
44         return;
45     }
46     for(int i=root;1;)
47     if(x<=a[i])
48         if(!c[i][0])
49         {
50             c[i][0]=N,fa
=i;
51             splay(N,0);
52             break;
53         }
54         else i=c[i][0];
55     else
56         if(!c[i][1])
57         {
58             c[i][1]=N,fa
=i;
59             splay(N,0);
60             break;
61         }
62         else i=c[i][1];
63 }
64 int main()
65 {
66     scanf("%d",&n);int ans=0;
67     for(int i=1;i<=n;i++)
68     {
69         scanf("%d",&x);
70         if(i==1) ans+=x;
71         else
72             ans+=min(upper(x),lower(x));
73         add(x);
74     }
75     printf("%d\n",ans);
76     return 0;
77 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: