题意:找离查找值最近的一个值
1)先用set 撸了一发
1 // File Name: first.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月15日 星期二 19时41分13秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #include<climits> 25 #include<queue> 26 27 using namespace std; 28 29 int main(){ 30 31 long long n ; 32 while(scanf("%lld",&n) != EOF) 33 { 34 long long x; 35 set<long long>a; 36 set<long long>::iterator l,en,be; 37 set<long long>::iterator r; 38 long long sum = 0 ; 39 scanf("%lld",&x); 40 sum += x; 41 a.insert(x); 42 for(int i = 2;i <= n;i ++) 43 { 44 scanf("%lld",&x); 45 if(a.find(x) != a.end()) continue; 46 47 a.insert(x); 48 en = a.end(); 49 --en; 50 if(a.find(x) == en) 51 { 52 l = a.find(x); 53 --l ; 54 // printf("**%lld ",*l); 55 sum += x - *l; 56 }else if(a.find(x) == a.begin()){ 57 l = a.find(x); 58 ++l ; 59 sum += *l -x; 60 // printf("**%lld ",*l); 61 }else { 62 l = a.find(x); 63 r = a.find(x); 64 r = ++r; 65 l = --l; 66 // printf("**%lld %lld ",*l,*r); 67 sum += min(x-*l,*r-x); 68 } 69 70 } 71 printf("%lld ",sum); 72 } 73 74 return 0; 75 }
测试数据 #1: Accepted, time=20ms, mem=1256KB, score=10
测试数据 #2: Accepted, time=0ms, mem=640KB, score=10
测试数据 #3: Accepted, time=0ms, mem=636KB, score=10
测试数据 #4: Accepted, time=10ms, mem=956KB, score=10
测试数据 #5: Accepted, time=30ms, mem=1996KB, score=10
测试数据 #6: Accepted, time=20ms, mem=1964KB, score=10
测试数据 #7: Accepted, time=20ms, mem=1620KB, score=10
测试数据 #8: Accepted, time=20ms, mem=1620KB, score=10
测试数据 #9: Accepted, time=20ms, mem=1244KB, score=10
测试数据 #10: Accepted, time=0ms, mem=640KB, score=10
Time = 140ms Mem = 1996KB Score= 100
2)treap 数组模拟树
要是学习了 nocow上面byvoid 的递归版本的代码
但是由于他当时是第一次敲,没有考虑到 root 节点也会旋转的性质,所以代码也只供参考
既然学习了我就对他的代码加上了一个root移动的性质,因为这颗平衡查找树只有插入这个操作
需要旋转节点,所以操作起来还是比较简单的。 其实是我对byvoid的代码理解错误,他的 root 指针是直接传引用进去的,所以能够更改root 的值。这就很巧妙
1 // File Name: treap1.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月17日 星期四 09时26分46秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define maxn 52767 25 using namespace std; 26 typedef struct { 27 int l , r , key , fix; 28 }node; 29 int ans = 1e9,temp; 30 class treap{ 31 public: 32 node p[maxn]; 33 int size,root; 34 treap(){ 35 srand(time(NULL)); 36 size = -1; 37 root = -1; 38 } 39 40 void rot_l(int &x) 41 { 42 int y = p[x].r; 43 p[x].r = p[y].l; 44 p[y].l = x; 45 x = y ; 46 } 47 48 void rot_r(int &x) 49 { 50 int y = p[x].l ; 51 p[x].l = p[y].r ; 52 p[y].r = x; 53 x = y ; 54 } 55 56 void insert(int &k,int tkey) 57 { 58 // printf("**%d ",k); 59 if(k == -1){ 60 if(size == -1) 61 root = 0; 62 k = ++size; 63 p[k].l = p[k].r = -1; 64 p[k].key = tkey; 65 p[k].fix = rand(); 66 }else if(tkey < p[k].key){ 67 insert(p[k].l,tkey); 68 if(p[p[k].l].fix > p[k].fix) 69 { 70 if(k == root) 71 { 72 root = p[k].l; 73 } 74 rot_r(k); 75 } 76 }else if(tkey > p[k].key){ 77 insert(p[k].r,tkey); 78 if(p[p[k].r].fix > p[k].fix) 79 { 80 if(k == root) 81 { 82 root = p[k].r; 83 } 84 rot_l(k); 85 } 86 }else { 87 return ; 88 } 89 } 90 void find(int k ) 91 { 92 // printf("**%d ",k); 93 ans = min(ans,abs(p[k].key - temp)); 94 if(p[k].key > temp && p[k].l != -1) 95 find(p[k].l); 96 else if(p[k].r != -1) 97 find(p[k].r); 98 } 99 }; 100 treap T; 101 int main(){ 102 // freopen("input.txt","r",stdin); 103 int m ; 104 while(scanf("%d",&m) != EOF && m) 105 { 106 // printf("%d ",m); 107 T = treap(); 108 int sum = 0 ; 109 scanf("%d",&temp); 110 sum += temp; 111 int p = T.root; 112 T.insert(p,temp); 113 for(int i = 1;i < m ;i ++) 114 { 115 scanf("%d",&temp); 116 ans = 1e9; 117 int p = T.root ; 118 T.find(T.root); 119 sum += ans ; 120 //printf("%d ",sum); 121 T.insert(p,temp); 122 } 123 printf("%d ",sum); 124 } 125 return 0; 126 }
测试数据 #1: Accepted, time=10ms, mem=792KB, score=10
测试数据 #2: Accepted, time=0ms, mem=640KB, score=10
测试数据 #3: Accepted, time=0ms, mem=636KB, score=10
测试数据 #4: Accepted, time=0ms, mem=684KB, score=10
测试数据 #5: Accepted, time=20ms, mem=1032KB, score=10
测试数据 #6: Accepted, time=0ms, mem=1020KB, score=10
测试数据 #7: Accepted, time=10ms, mem=912KB, score=10
测试数据 #8: Accepted, time=20ms, mem=912KB, score=10
测试数据 #9: Accepted, time=20ms, mem=784KB, score=10
测试数据 #10: Accepted, time=0ms, mem=640KB, score=10
Time = 80ms Mem = 1032KB Score= 100
可以看出,这里还是比set要略微快一点。
treap 指针
用CLJ 的代码又撸了一发, 时间竟然比数组实现的还快。
解题代码:
1 // File Name: treap.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月22日 星期二 09时06分23秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 using namespace std; 25 26 const int inf = ~0U>>1; 27 int mi = 1e9 ; 28 class treap 29 { 30 struct node{ 31 int value , key ,size; 32 node(int v, node *n):value(v) 33 {c[0] = c[1]= n; size = 1; key = rand()-1;} 34 void rz(){size =c[0]->size + c[1]->size+1;} 35 node*c[2]; 36 }*root,*null; 37 void rot(node *&t,bool d) 38 { 39 node *c = t->c[d]; 40 t->c[d] = c->c[!d]; 41 c->c[!d] = t; 42 t->rz();c->rz(); 43 t = c; 44 } 45 void insert(node *&t,int x) 46 { 47 if(t == null) 48 { 49 t = new node(x,null); 50 return ; 51 } 52 if(x == t->value) return; 53 bool d = x > t->value; 54 insert(t->c[d],x); 55 if(t->c[d]->key < t->key) //把小的随机值移动到上面 56 rot(t,d); 57 else t->rz(); 58 } 59 void Delete(node *&t,int x) 60 { 61 if(t == null) return; 62 if(t->value == x) //將这个值一直旋转到叶子节点然后删除 63 { 64 bool d = t->c[1]->key < t->c[0]->key; 65 if(t->c[d] == null) 66 { 67 delete t; 68 t = null; 69 return ; 70 } 71 rot(t,d); 72 Delete(t->c[!d],x); 73 } 74 else{ 75 bool d = x>t->value; 76 Delete(t->c[d],x); 77 } 78 t->rz(); 79 } 80 int select(node *t ,int k ) 81 { 82 int r = t->c[0]->size; 83 if(k == r) 84 return t->value; 85 if(k < r) return select(t->c[0],k); 86 return select(t->c[1], k - r - 1); 87 } 88 int rank(node *t , int x) 89 { 90 if(t == null) return 0 ; 91 int r = t->c[0]->size; 92 if(x == t->value) 93 return r; 94 if(x < t->value) return rank(t->c[0],x); 95 return r+1+rank(t->c[1],x); 96 } 97 void find(node *t, int x ) 98 { 99 if(t == null) 100 return ; 101 mi = min(abs(x-t->value),mi); 102 if(x > t->value) 103 find(t->c[1],x); 104 else find(t->c[0],x); 105 } 106 public: 107 treap() 108 { 109 null = new node(0,0); 110 null ->size = 0 ; 111 null ->key = inf; 112 root = null; 113 } 114 void ins(int x) 115 { 116 insert(root,x); 117 } 118 int sel(int k) 119 { 120 if(k > root->size) return -inf; 121 return select(root,k-1); 122 } 123 int ran(int x) 124 { 125 return rank(root,x); 126 } 127 void del(int x) 128 { 129 Delete(root,x); 130 } 131 void fin(int x) 132 { 133 find(root,x); 134 } 135 }; 136 int main(){ 137 //printf("%d ",inf); 138 //freopen("in","r",stdin); 139 int m ; 140 scanf("%d",&m); 141 srand(time(NULL)); 142 // printf("**** "); 143 treap T; 144 int temp ; 145 scanf("%d",&temp); 146 long long sum = temp ; 147 T.ins(temp); 148 for(int i = 1 ;i < m;i ++) 149 { 150 scanf("%d",&temp); 151 mi = 1e9; 152 T.fin(temp); 153 T.ins(temp); 154 sum += mi; 155 // printf("**** "); 156 } 157 printf("%lld ",sum); 158 return 0; 159 }
测试数据 #1: Accepted, time=10ms, mem=1272KB, score=10
测试数据 #2: Accepted, time=0ms, mem=640KB, score=10
测试数据 #3: Accepted, time=0ms, mem=636KB, score=10
测试数据 #4: Accepted, time=0ms, mem=976KB, score=10
测试数据 #5: Accepted, time=20ms, mem=2016KB, score=10
测试数据 #6: Accepted, time=10ms, mem=1984KB, score=10
测试数据 #7: Accepted, time=10ms, mem=1640KB, score=10
测试数据 #8: Accepted, time=10ms, mem=1644KB, score=10
测试数据 #9: Accepted, time=10ms, mem=1264KB, score=10
测试数据 #10: Accepted, time=0ms, mem=640KB, score=10
Time = 70ms Mem = 2016KB Score= 100