题意:找离查找值最近的一个值

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\n",*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\n",*l);
61           }else {
62               l = a.find(x);
63               r = a.find(x);
64               r = ++r;
65               l = --l;
66         //      printf("**%lld %lld\n",*l,*r);
67               sum += min(x-*l,*r-x);
68           }
69 
70       }
71       printf("%lld\n",sum);
72     }
73     
74     return 0;
75 }
View Code

测试数据 #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\n",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\n",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\n",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\n",sum); 
121           T.insert(p,temp);
122        }
123      printf("%d\n",sum);
124    }
125 return 0;
126 }
View Code

 

测试数据 #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\n",inf);   
138     //freopen("in","r",stdin);
139     int m ; 
140     scanf("%d",&m);
141     srand(time(NULL));
142     // printf("****\n");
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("****\n");
156     }
157     printf("%lld\n",sum);
158     return 0;
159 }
View Code

测试数据 #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

posted on 2014-07-15 23:53  dark_dream  阅读(252)  评论(0编辑  收藏  举报