zoukankan      html  css  js  c++  java
  • HYSBZ 1208 宠物收养所 (Splay树)

    题意:一家宠物收养所负责处理领养者与遗弃宠物业务,有人来领宠物,则领一只最理想的。若没有宠物了,领养者们就得等到宠物来,宠物一来立刻送给其中一个等待者。如果有两个理想的选择,则选择那个值较小的。收养所时刻只存在人or宠物or没有存在任何!

    思路:

      这题主要是树中可能存在人或者宠物,但两者不可能同时存在,因为一旦存在,必须有对象被配对并从树中删除。 所有函数独自写起来都是很简单的,但是合起来使用时就得小心了,得配合一点。

      要时刻注意树中是否还有节点,若没有,则可能要树要换种类了。

      1 #include <bits/stdc++.h>
      2 #define pii pair<int,int>
      3 #define INF 0x3f7f7f7f
      4 #define LL long long
      5 using namespace std;
      6 const int N=40020;
      7 const int mod=1000000;
      8 
      9 struct node
     10 {
     11     int key, pre, ch[2];
     12 }nod[N];
     13 int node_cnt, root, flag;
     14 
     15 int create_node(int v,int far)
     16 {
     17     nod[node_cnt].ch[0]=nod[node_cnt].ch[1]=0;
     18     nod[node_cnt].pre=far;
     19     nod[node_cnt].key=v;
     20     return node_cnt++;
     21 }
     22 
     23 void Rotate(int t,int d)
     24 {
     25     int son=nod[t].ch[d];
     26     int far=nod[t].pre;
     27     int gra=nod[far].pre;
     28     nod[t].pre=gra;
     29     nod[far].pre=t;
     30     nod[son].pre=far;
     31     nod[t].ch[d]=far;
     32     nod[far].ch[d^1]=son;
     33     nod[gra].ch[ nod[gra].ch[1]==far ]=t;
     34 }
     35 
     36 
     37 int Insert(int t,int v)
     38 {
     39     if(t==0)    return  root=create_node(v, 0); //树中还没有节点。
     40     if( v < nod[t].key )
     41     {
     42         if(nod[t].ch[0])  return Insert(nod[t].ch[0], v);
     43         else              return nod[t].ch[0]=create_node(v, t);
     44     }
     45     else
     46     {
     47         if(nod[t].ch[1])  return Insert(nod[t].ch[1], v);
     48         else              return nod[t].ch[1]=create_node(v, t);
     49     }
     50 }
     51 
     52 void Splay(int t, int goal)
     53 {
     54     while(nod[t].pre!=goal)
     55     {
     56         int f=nod[t].pre, g=nod[f].pre;
     57         if(g==goal)    Rotate( t, nod[f].ch[0]==t );
     58         else
     59         {
     60             int d1=nod[f].ch[0]==t, d2=nod[g].ch[0]==f;
     61             if(d1==d2)    Rotate(f, d1),Rotate(t, d1);
     62             else          Rotate(t, d1),Rotate(t, d2);
     63         }
     64     }
     65     if(goal==0) root=t; //随时更新根!
     66 }
     67 
     68 int Find(int t,int v)   //在子树t中找到值为v的点,返回点号
     69 {
     70     while(t)
     71     {
     72         if(v==nod[t].key)   return t;
     73         if(v<nod[t].key)    t=nod[t].ch[0];
     74         else                t=nod[t].ch[1];
     75     }
     76     return 0;   //找不到
     77 }
     78 
     79 int Find_pre(int t,int v)
     80 {
     81     int val=-1;
     82     while(t)
     83     {
     84         if(nod[t].key<v)    val=max(val, nod[t].key);
     85         if(v<nod[t].key)    t=nod[t].ch[0];
     86         else                t=nod[t].ch[1];
     87     }
     88     if(val<0)   return INF;
     89     return val;
     90 }
     91 
     92 int Find_bac(int t,int v)
     93 {
     94     int val=INF;
     95     while(t)
     96     {
     97         if(nod[t].key>v)    val=min(val, nod[t].key);
     98         if(v<nod[t].key)    t=nod[t].ch[0];
     99         else                t=nod[t].ch[1];
    100     }
    101     return val;
    102 }
    103 
    104 void Delete(int v)  //在树中删除值为v的任意一个点
    105 {
    106     Splay(Find(root, v), 0);   //将目标旋转到根
    107     int L=nod[root].ch[0];
    108     int R=nod[root].ch[1];
    109     if(L==0 && R==0)    root=0;
    110     else if(R==0)    //没有右子树
    111     {
    112         nod[L].pre=0;
    113         root=L;
    114     }
    115     else if(L==0)    //没有左子树
    116     {
    117         nod[R].pre=0;
    118         root=R;
    119     }
    120     else            //有前有后
    121     {
    122         while(nod[R].ch[0]) R=nod[R].ch[0]; //找到后继
    123         Splay(R, root);
    124         nod[R].ch[0]=L;
    125         nod[R].pre=0;
    126         nod[L].pre=R;
    127         root=R;
    128     }
    129 }
    130 
    131 int main()
    132 {
    133     //freopen("input.txt", "r", stdin);
    134     int n, ans, a, b, contain;
    135     while(cin>>n)
    136     {
    137         flag=node_cnt=7;
    138         contain=root=ans=0;
    139         while(n--)
    140         {
    141             scanf("%d%d",&a,&b);
    142             if(a==flag || contain==0)    // 树为空 or 树中是同种类 则 插入
    143             {
    144                 flag=a;
    145                 contain++;
    146                 Splay(Insert(root, b), 0);
    147             }
    148             else
    149             {
    150                 if(Find(root, b))    Delete(b); //刚好有值为b的。
    151                 else
    152                 {
    153                     int L=Find_pre(root, b);
    154                     int R=Find_bac(root, b);
    155                     if( abs(L-b)<=abs(R-b) )      //L和R不可能同时为INF。
    156                     {
    157                         ans=(ans+abs(L-b))%mod;
    158                         Delete(L);
    159                     }
    160                     else
    161                     {
    162                         ans=(ans+abs(R-b))%mod;
    163                         Delete(R);
    164                     }
    165                 }
    166                 contain--;
    167             }
    168         }
    169         printf("%d
    ", ans );
    170     }
    171     return 0;
    172 }
    AC代码
  • 相关阅读:
    Ubuntu配置sublime text 3的c编译环境
    ORA-01078错误举例:SID的大写和小写错误
    linux下多进程的文件拷贝与进程相关的一些基础知识
    ASM(四) 利用Method 组件动态注入方法逻辑
    基于Redis的三种分布式爬虫策略
    Go语言并发编程总结
    POJ2406 Power Strings 【KMP】
    nyoj 会场安排问题
    Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    Java的String、StringBuffer和StringBuilder的区别
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4749303.html
Copyright © 2011-2022 走看看