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

 最近各种瞎写数论题,感觉需要回顾一下数据结构

写一发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[N][0]=c[N][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[N]=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[N]=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
",ans);
76     return 0;
77 }
原文地址:https://www.cnblogs.com/wanglichao/p/6291023.html