bzoj 1588 营业额统计

题目大意:

一些数,依次加进去,每次加进去一个数a之前 在已经加进去的数找一个数k

使|k-a|最小,求这个最小值

思路:

用splay维护已经加进去的数

每次查询时查询它的前驱与后继 求出最小值

并把它splay到根节点上去(使它的前驱和后继分别在它的左子树和右子树里)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 100100 
12 #define MOD 1000000007
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int ch[MAXN][2],fa[MAXN],sz,val[MAXN],rt,same;
22 int which(int x) {return x==ch[fa[x]][1];}
23 int find_pre()
24 {
25     int pos=ch[rt][0];
26     while(ch[pos][1]) pos=ch[pos][1];
27     return pos;
28 }
29 int find_sub()
30 {
31     int pos=ch[rt][1];
32     while(ch[pos][0]) pos=ch[pos][0];
33     return pos;
34 }
35 void rotate(int pos)
36 {
37     int f=fa[pos],ff=fa[f],k=which(pos);
38     ch[f][k]=ch[pos][k^1],fa[ch[f][k]]=f,fa[f]=pos,ch[pos][k^1]=f,fa[pos]=ff;
39     if(ff) ch[ff][ch[ff][1]==f]=pos;
40 }
41 void splay(int x)
42 {
43     for(int f;f=fa[x];rotate(x))
44         if(fa[f]) rotate((which(x)==which(f)?f:x));
45     rt=x;
46 }
47 void Insert(int x)
48 {
49     int pos=rt,f=0;
50     while(1)
51     {
52         if(val[pos]==x) {splay(pos);same=1;return ;}
53         f=pos,pos=ch[pos][x>val[pos]];
54         if(!pos)
55         {
56             ch[++sz][0]=ch[sz][1]=0,fa[sz]=f,val[sz]=x,ch[f][x>val[f]]=sz;
57             splay(sz);return ;
58         }
59     }
60 }
61 void insert(int x)
62 {
63     if(!rt) {val[++sz]=x,ch[sz][0]=ch[sz][1]=fa[sz]=0,rt=sz;return;}
64     Insert(x);
65 }
66 int main()
67 {
68     int T=read(),x,pre,tmp,sub,ans=0;
69     while(T--)
70     {
71         x=read(),tmp=inf,same=0;
72         insert(x);
73         if(same) continue;
74         pre=find_pre(),sub=find_sub();
75         if(pre) tmp=min(tmp,x-val[pre]);
76         if(sub) tmp=min(tmp,val[sub]-x);
77         ans+=(tmp==inf?x:tmp);
78     }
79     printf("%d",ans);
80 }
View Code

 

posted @ 2017-11-03 16:20  jack_yyc  阅读(166)  评论(0编辑  收藏  举报