BZOJ--1588(Treap / STL)

2015-03-17 21:22:46

思路:题意就是不断地往一个集合里面插入数,每插入一个数前,都要查询集合中距离这个数最近的数,并累加差值。最后输出总差值。

  想法(1)用Treap维护这个集合,对于查询,分开两部分,先查询比这个数大且距离最近的数,再查询小于等于这个数且距离最近的数。查询过程可以利用treap的性质逐层向下。

  想法(2)用STL的set<int>搞定,对于查询,调用set.lower_bound(value)... 哈哈,黑科技呀~

 

(1)Treap

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <stack>
  9 #include <queue>
 10 #include <string>
 11 #include <iostream>
 12 #include <algorithm>
 13 using namespace std;
 14 
 15 #define MEM(a,b) memset(a,b,sizeof(a))
 16 #define REP(i,n) for(int i=1;i<=(n);++i)
 17 #define REV(i,n) for(int i=(n);i>=1;--i)
 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
 21 #define MP(a,b) make_pair(a,b)
 22 
 23 typedef long long ll;
 24 typedef pair<int,int> pii;
 25 const int INF = (1 << 30) - 1;
 26 const int MAXN = 100000;
 27 
 28 int N;
 29 int UP,DOWN;
 30 
 31 struct Treap{
 32     int root,tcnt;
 33     int key[MAXN],pro[MAXN],son[MAXN][2];
 34     void clear(){
 35         root = 0;
 36         tcnt = 0;
 37         pro[0] = INF;
 38     }
 39     void rotate(int &x,int t){
 40         int y = son[x][t];
 41         son[x][t] = son[y][1 - t];
 42         son[y][1 - t] = x;
 43         x = y;
 44     }
 45     void _insert(int &x,int k){
 46         if(x){ //非空树
 47             if(key[x] != k){
 48                 int t = k > key[x];
 49                 _insert(son[x][t],k);
 50                 if(pro[son[x][t]] < pro[x]) rotate(x,t);
 51             }
 52         }
 53         else{
 54             x = ++tcnt;
 55             pro[x] = rand();
 56             key[x] = k;
 57             son[x][0] = son[x][1] = 0;
 58         }
 59     }
 60     void _up(int &x,int k){
 61         if(key[x] == k){
 62             UP = k;
 63             return;
 64         }
 65         else if(k > key[x]){
 66             if(son[x][1]) _up(son[x][1],k);
 67         }
 68         else{
 69             UP = min(UP,key[x]);
 70             if(son[x][0]) _up(son[x][0],k);
 71         }
 72     }
 73     void _down(int &x,int k){
 74         if(key[x] == k){
 75             DOWN = k;
 76             return;
 77         }
 78         else if(k > key[x]){
 79             DOWN = max(DOWN,key[x]);
 80             if(son[x][1]) _down(son[x][1],k);
 81         }
 82         else{
 83             if(son[x][0]) _down(son[x][0],k);
 84         }
 85     }
 86     void insert(int k){
 87         _insert(root,k);
 88     }
 89     void up(int k){
 90         _up(root,k);
 91     }
 92     void down(int k){
 93         _down(root,k);
 94     }
 95 }tp;
 96 
 97 int main(){
 98     int a;
 99     N = 0;
100     while(scanf("%d",&N) != EOF){
101         tp.clear();
102         a = 0;
103         scanf("%d",&a);
104         tp.insert(a);
105         int sum = a;
106         REP(i,N - 1){
107             a = 0;
108             scanf("%d",&a);
109             UP = INF,DOWN = -INF;
110             tp.up(a);
111             tp.down(a);
112             tp.insert(a);
113             sum += min(UP - a,a - DOWN);
114         }
115         printf("%d\n",sum);
116     }
117     return 0;
118 }
View Code

 

(2)set

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=1;i<=(n);++i)
17 #define REV(i,n) for(int i=(n);i>=1;--i)
18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
20 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
21 #define MP(a,b) make_pair(a,b)
22 
23 typedef long long ll;
24 typedef pair<int,int> pii;
25 const int INF = (1 << 30) - 1;
26 
27 int N;
28 set<int> st;
29 
30 int main(){
31     int a;
32     N = 0;
33     while(scanf("%d",&N) != EOF){
34         st.clear();
35         a = 0;
36         scanf("%d",&a);
37         st.insert(a);
38         int res,sum = a;
39         set<int>::iterator it;
40         REP(i,N - 1){
41             a = 0;
42             scanf("%d",&a);
43             res = INF;
44             it = st.lower_bound(a);
45             if(it != st.end()) res = min(res,(*it) - a);
46             if(it != st.begin()){
47                 it--;
48                 res = min(res,a - (*it));
49             }
50             st.insert(a);
51             sum += res;
52         }
53         printf("%d\n",sum);
54     }
55     return 0;
56 }    
View Code

 

posted @ 2015-03-17 21:48  Naturain  阅读(145)  评论(0编辑  收藏  举报