hust 1007 平衡树

 思路:该题目要求在log(n)时间内进行插入,删除,求后继操作,可以使用平衡树解决,由于不用求名次或者取k大,所以可以和使用stl set来解决,可以存在相同的数,所以要用multiset.

 

代码如下

  1. #include <set>
  2. #include <algorithm>
  3. #include <iostream>
  4. using namespace std;
  5. int main()
  6. {
  7.     int i,j,k,t;
  8.     int n, q, y;
  9.     
  10.     scanf("%d", &t);
  11.     for(k = 1; k <= t; k++)
  12.     {
  13.         printf("Case %d:/n", k);
  14.         multiset<int> a;
  15.         scanf("%d%d%d", &n, &q, &y);
  16.         
  17.         for(i = 0; i < n; i++)
  18.         {
  19.             scanf("%d", &j);
  20.             a.insert(j);
  21.         }
  22.         set<int>::iterator low;
  23.         for(i = 0; i < q; i++)
  24.         {
  25.             scanf("%d", &j);
  26.             low = a.lower_bound(j);
  27.             //printf("   %d %d/n", j, *low);
  28.             if(low == a.end() || *low-j > y) puts("-1");
  29.             else
  30.             {
  31.                 printf("%d/n", *low);
  32.                 a.erase(low);
  33.             }
  34.         }
  35.     }
  36. }

 

 

为了练习的目的,再次用SBT写了一遍,思路相同

 

  1. #include <algorithm> 
  2. using namespace std;
  3. struct sbt_node
  4. {
  5.     int key,sz;
  6.     sbt_node *lc, *rc;
  7.     sbt_node(int x, int y);
  8. }NIL=sbt_node(0,0),*nil=&NIL;
  9. sbt_node::sbt_node(int x, int y=1)
  10. {
  11.     key=x,sz=y;
  12.     lc=rc=nil;
  13. }
  14. typedef sbt_node *node;
  15. node root;
  16. void right_rotate(node &y)
  17. {
  18.     node x = y->lc;
  19.     y->lc = x->rc;
  20.     x->rc = y;
  21.     x->sz = y->sz;
  22.     y->sz = y->lc->sz + y->rc->sz +1;
  23.     y = x;
  24. }
  25. void left_rotate(node &x)
  26. {
  27.     node y = x->rc;
  28.     x->rc = y->lc;
  29.     y->lc = x;
  30.     y->sz = x->sz;
  31.     x->sz = x->lc->sz + x->rc->sz +1;
  32.     x = y;
  33. }
  34. void maintain(node &t, bool right_high)
  35. {
  36.     if(!right_high)
  37.     {
  38.         if(t->lc==nil)return;
  39.         if(t->lc->lc->sz > t->rc->sz)
  40.         {
  41.             right_rotate(t);
  42.         }
  43.         else if(t->lc->rc->sz > t->rc->sz)
  44.         {
  45.             left_rotate(t->lc);
  46.             right_rotate(t);
  47.         }
  48.         else return;
  49.     }
  50.     else
  51.     {
  52.         if(t->rc==nil)return;
  53.         if(t->rc->rc->sz > t->lc->sz)
  54.         {
  55.             left_rotate(t);
  56.         }
  57.         else if(t->rc->lc->sz > t->lc->sz)
  58.         {
  59.             right_rotate(t->rc);
  60.             left_rotate(t);
  61.         }
  62.         else return;
  63.     }
  64.     maintain(t->lc, 0);
  65.     maintain(t->rc, 1);
  66.     maintain(t, 0);
  67.     maintain(t, 1);
  68. }
  69. void insert(node &t, int x)
  70. {
  71.     if(t==nil)
  72.     {
  73.         t = new sbt_node(x);
  74.     }
  75.     else
  76.     {
  77.         t->sz++;
  78.         if(x < t->key) insert(t->lc, x);
  79.         else insert(t->rc, x);
  80.     }
  81.     maintain(t, x >= t->key);
  82. }
  83. void del(node &t, int x)
  84. {
  85.     if(t==nil)return;
  86.     t->sz--;
  87.     if(x < t->key) del(t->lc, x);
  88.     else if(x > t->key) del(t->rc, x);
  89.     if(x == t->key)
  90.     {
  91.         if(t->lc==nil)
  92.         {
  93.             t = t->rc;
  94.         }
  95.         else if(t->rc==nil)
  96.         {
  97.             t = t->lc;
  98.         }
  99.         else
  100.         {
  101.             node tmp=t->rc;
  102.             while(tmp->lc != nil)tmp = tmp->lc;
  103.             t->key = tmp->key;
  104.             del(t->rc, tmp->key);
  105.         }
  106.     }
  107. }
  108. int succ(node t, int x)
  109. {
  110.     if(t==nil)return -1;
  111.     if(x == t->key) return x;
  112.     else if(x > t->key) return succ(t->rc, x);
  113.     else
  114.     {
  115.         int tmp=succ(t->lc,x);
  116.         if(tmp == -1)
  117.         {
  118.             return t->key;
  119.         }
  120.         else return tmp;
  121.     }
  122. }
  123. void print2(node t)
  124. {
  125.     if(t==nil)return;
  126.     putchar('(');
  127.     print2(t->lc);
  128.     printf("size[%d]=%d/t", t->key, t->sz);
  129.     print2(t->rc);
  130.     putchar(')');
  131. }
  132. void print(node t)
  133. {
  134.     print2(t);
  135.     puts("");
  136. }
  137. /*
  138. 2
  139. 10 10 10
  140. 7 5 3 2 1 2 3 5 7 9
  141. 1 5 5 5 5 5 5 5 5 5
  142. 10 10 10
  143. 1 2 3 4 5 6 7 8 9 10
  144. 1 2 3 4 3 3 3 9 9 9
  145. */
  146. int main()
  147. {
  148.     int i, j, k, t;
  149.     int n, q, y;
  150.     scanf("%d", &t);
  151.     for(k = 1; k <= t; k++)
  152.     {
  153.         root = nil;
  154.         scanf("%d%d%d", &n, &q, &y);
  155.         for(i = 0; i < n; i++)
  156.         {
  157.             scanf("%d", &j);
  158.             insert(root, j);
  159.         }
  160.         printf("Case %d:/n", k);
  161.         for(i = 0; i < q; i++)
  162.         {
  163.             scanf("%d", &j);
  164.             int tmp = succ(root, j);
  165.             if(tmp == -1 || tmp-j>y) puts("-1");
  166.             else
  167.             {
  168.                 del(root, tmp);
  169.                 printf("%d/n", tmp);
  170.             }
  171.             //print(root); 
  172.         }
  173.     }
  174.     return 0;
  175. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值