BZOJ--1588(Treap / STL)
2015-03-17 21:22:46
思路:题意就是不断地往一个集合里面插入数,每插入一个数前,都要查询集合中距离这个数最近的数,并累加差值。最后输出总差值。
想法(1)用Treap维护这个集合,对于查询,分开两部分,先查询比这个数大且距离最近的数,再查询小于等于这个数且距离最近的数。查询过程可以利用treap的性质逐层向下。
想法(2)用STL的set<int>搞定,对于查询,调用set.lower_bound(value)... 哈哈,黑科技呀~
(1)Treap
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
(2)set
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }