poj 3481 double Queue(Splay树 模板解读)

来源:互联网 发布:如何编写python程序 编辑:程序博客网 时间:2024/05/01 09:25

题意:

每个顾客有个编号和优先级,银行每次可以添加顾客的要求进队列,
且保证队列中当前任意顾客的编号和优先级都不同.
银行可以执行先服务最大优先级的顾客或者先服务最小优先级的顾客操作.
对于每个服务,输出顾客的编号.

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cstdlib>#include <cmath>#include <utility>#include <vector>#include <queue>#include <map>#include <set>#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)>(y)?(y):(x))#define INF 0x3f3f3f3f#define MAXN 100005using namespace std;int cnt=1,rt=0;struct Tree{    int key,size,fa,son[2],num;    void set(int _key,int _size,int _fa,int _num)    {        key=_key;        size=_size;        fa=_fa;        son[0]=son[1]=0;        num=_num;    }}T[MAXN];inline void PushUp(int x){    T[x].size=T[T[x].son[0]].size+T[T[x].son[1]].size+1;}inline void Rotate(int x,int p){    int y=T[x].fa;    T[y].son[!p]=T[x].son[p];    T[T[x].son[p]].fa=y;    T[x].fa=T[y].fa;    if(T[x].fa)        T[T[x].fa].son[T[T[x].fa].son[1]==y]=x;    T[x].son[p]=y;    T[y].fa=x;    PushUp(y);    PushUp(x);}void Splay(int x,int To){    while(T[x].fa!=To) //直到父节点为To    {        if(T[T[x].fa].fa==To) //如果父节点的父节点==To 单旋            Rotate(x,T[T[x].fa].son[0]==x);        else //如果的父节点的父节点!=to 双旋        {            int y=T[x].fa,z=T[y].fa; //y是父节点,z是父节点的父节点            int p=(T[z].son[0]==y);//y是不是在父节点的0路线            if(T[y].son[p]==x)  //这里判断是不是和父节点所在路线相反            Rotate(x,!p),Rotate(x,p);// 如果相反 就是之字形            else                Rotate(y,p),Rotate(x,p);//相同 一字型        }    }    if(To==0) rt=x;}int prev(){    int x=T[rt].son[0];    if(!x) return 0;    while(T[x].son[1])        x=T[x].son[1];    return x;}int succ(){    int x=T[rt].son[1];    if(!x)return 0;    while(T[x].son[0])        x=T[x].son[0];    Splay(x,0);    return x;}void Insert(int key,int num)//插入key 并且将该节点转移到根处{    if(!rt)        T[rt=cnt++].set(key,1,0,num);    else    {        int x=rt,y=0;        while(x)        {            y=x;            x=T[x].son[key>T[x].key];        }        T[x = cnt++].set(key,1,y,num);        T[y].son[key>T[y].key]=x;        Splay(x,0);    }}int find(int key) //返回值为key的节点 若无返回0 若有将其转移到根处{    int x=rt;    while(x&&T[x].key!=key)        x=T[x].son[key>T[x].key];    if(x) Splay(x,0);    return x;}int GetPth(int p)   //获得第p小的节点 并将其转移到根处{    if(!rt) return 0;    int x=rt,ret=0;    while(x)    {        if(p==T[T[x].son[0]].size+1)            break;        if(p>T[T[x].son[0]].size+1) //判断是第p个是在左边还是右边        {            p-=T[T[x].son[0]].size+1;            x=T[x].son[1];        }        else             x=T[x].son[0];    }    Splay(x,0);    return x;}void Delete(int key)//删除值为key的节点 若有重点只删其中一个 x的前驱移动到根处{    int x=find(key); //找到与key值相同的    if(!x) return ; //如果没有就return    int y=T[x].son[0];     while(T[y].son[1]) //找到左边叶子结点        y=T[y].son[1];    int z=T[x].son[1];  //找到右边叶子结点    while(T[z].son[0])        z=T[z].son[0];    if(!y&&!z)  //如果这是根结点    {        rt=0;        return ;    }    if(!y) //只有右叶子结点    {        Splay(z,0); //把z调到最高点然后把x删去        T[z].son[0]=0; //把x删去        PushUp(z);        return ;    }    if(!z) //只有左叶子结点    {        Splay(y,0);         T[y].son[1]=0; //把y调到最低点然后把x删去        PushUp(y); //把x删去        return ;    }    Splay(y,0);    Splay(z,y);    T[z].son[0]=0;    PushUp(z);    PushUp(y);}int main (){    int p, key, num, x;    while(scanf("%d", &p) && p)    {        switch (p)        {            case 1:                scanf("%d%d", &num, &key);                Insert(key, num);                break;            case 2:                x=GetPth(T[rt].size);                if(x)                {                    printf("%d\n",T[x].num);                    Delete(T[x].key);                }                else                    printf("0\n");                break;            case 3:                x=GetPth(1);                if(x)                {                    printf("%d\n",T[x].num);                    Delete(T[x].key);                }                else                    printf("0\n");        }    }    return 0;}

另一个模板

#include<stdio.h>  #include<string.h>  #include<algorithm>  #include<iostream>  #include<vector>  using namespace std;  #define maxn 1100000  #define mem(a,b) memset(a,b,sizeof(a))  #define root10 ch[ch[root][1]][0]  #define root1 ch[root][1]  int size[maxn];  int ch[maxn][2];  int pre[maxn];  int root,tot;  int key[maxn];  int val[maxn];  int n;  int pos;  void Treaval(int x) {      if(x) {          Treaval(ch[x][0]);          printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d \n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);          Treaval(ch[x][1]);      }  }  void debug() {printf("root:%d\n",root);Treaval(root);}  //以上Debug  void init()  {  }  void newnode(int &x,int k,int p,int father)  {      x=++tot;      pre[x]=father;      size[x]=1;      ch[x][0]=ch[x][1]=0;      key[x]=p;      val[x]=k;  }  void push_down(int x)  {  }  void push_up(int x)  {  }  void rot(int x,int kind)  {      int y=pre[x];      push_down(y);      push_down(x);      ch[y][!kind]=ch[x][kind];      pre[ch[x][kind]]=y;      if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;      pre[x]=pre[y];      ch[x][kind]=y;      pre[y]=x;      push_up(y);      push_up(x);  }  void splay(int x,int goal)  {      push_down(x);      while(pre[x]!=goal)      {          if(pre[pre[x]]==goal)          {              push_down(pre[x]);              push_down(x);              rot(x,ch[pre[x]][0]==x);          }          else          {              int y=pre[x];              push_down(pre[y]);              push_down(y);              push_down(x);              int kind=ch[pre[y]][0]==y;              if(ch[y][kind]==x)              {                  rot(x,!kind);                  rot(x,kind);              }              else              {                  rot(y,kind);                  rot(x,kind);              }          }      }      push_up(x);      if(goal==0)root=x;  }  void insert(int k,int p)  {      int rt=root;      int r=root;      while(rt!=0)      {          r=rt;          if(key[rt]<p)rt=ch[rt][1];          else rt=ch[rt][0];          //cout<<r<<" "<<rt<<endl;      }      newnode(ch[r][key[r]<p],k,p,r);      splay(ch[r][key[r]<p],root);      ch[0][0]=ch[0][1]=0;  }  int get_min(int rt)  {      while(ch[rt][0])rt=ch[rt][0];      if(rt==root)root=ch[rt][1];      ch[pre[rt]][0]=ch[rt][1];      pre[ch[rt][1]]=pre[rt];      return val[rt];  }  int get_max(int rt)  {      while(ch[rt][1])rt=ch[rt][1];      if(rt==root)root=ch[rt][0];      ch[pre[rt]][1]=ch[rt][0];      pre[ch[rt][0]]=pre[rt];      return val[rt];  }  int main()  {      root=tot=0;      int op,k,p;      while(~scanf("%d",&op)&&(op))      {          if(op==1)          {              scanf("%d%d",&k,&p);              insert(k,p);          }          if(op==2)          {              printf("%d\n",get_max(root));          }          if(op==3)          {              printf("%d\n",get_min(root));          }       //   debug();      }      return 0;  }  
0 0
原创粉丝点击