zoukankan      html  css  js  c++  java
  • HNOI2002 营业额统计 平衡查找树

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

    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 }
    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
    ",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 }
    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
    ",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 }
    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

    没有梦想,何谈远方
  • 相关阅读:
    基于vue的可视化编辑器
    IOS系统兼容input keyup事件
    js滚动事件实现滚动触底加载
    移动端 input 输入框实现自带键盘“搜索“功能并修改X
    clipboard.js兼容ios
    js实现点击复制网页内容(基于clipboard.js)
    js实现点击复制网页内容(基于execCommand)
    knn 数字识别
    knn 算法 k个相近邻居
    sklearn 线性回归
  • 原文地址:https://www.cnblogs.com/zyue/p/3847742.html
Copyright © 2011-2022 走看看