poj3481 Double Queue(set模拟or splay)

来源:互联网 发布:手机指南针软件 编辑:程序博客网 时间:2024/05/16 15:01

题目链接

题目意思明确。可以用两个set来模拟,一个大的优先,一个小的优先,同时删除、同时加入。

struct item1 {    int k, p;    item1() {}    item1(int k, int p) : k(k), p(p) {}    bool operator < (const item1& rhs) const {        return p < rhs.p;    }};struct item2 {    int k, p;    item2() {}    item2(int k, int p) : k(k), p(p) {}    bool operator < (const item2& rhs) const {        return p > rhs.p;    }};set<item1> st1;set<item2> st2;int main(int argc, const char * argv[]){        int op;    while(~scanf("%d", &op) && op) {        if (op == 1) {            int k,p;            scanf("%d%d", &k, &p);            st1.insert(item1(k, p));            st2.insert(item2(k, p));        }else if (op == 2) {            if (st2.empty()) {                printf("0\n");                continue;            }            item2 temp2 = *st2.begin();            st2.erase(temp2);            item1 temp1(temp2.k, temp2.p);            st1.erase(temp1);            printf("%d\n", temp2.k);        }else if (op == 3) {            if (st1.empty()) {                printf("0\n");                continue;            }            item1 temp1 = *st1.begin();            st1.erase(temp1);            item2 temp2(temp1.k, temp1.p);            st2.erase(temp2);            printf("%d\n", temp1.k);        }    }    return 0;}

也可以算成splay的入门题,只要保持树的中序遍历是有序的就行。
百度的图讲解很多,易懂。

#include <stdio.h>#define MAXN 100005struct TreeNode{    //键,子树大小,父节点编号,两个儿子节点编号,当前节点的附加信息    int key, size, fa, son[2], num;    TreeNode() {}    TreeNode(int _key, int _size, int _fa, int _num)    {        key = _key;size = _size;fa = _fa;        num = _num;son[0] = son[1] = 0;    }}T[MAXN];struct SplayTree {    int rt, cnt;    void init(){cnt = 1, rt = 0;}    void PushUp(int x)    {        T[x].size = T[T[x].son[0]].size + T[T[x].son[1]].size + 1;    }    /*p是旋转方向,旋转后x的深度-1*/    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;        /*y under x*/        PushUp(y);        PushUp(x);    }    /*x旋转到to下面*/    void Spaly(int x, int to)    {        while(T[x].fa != to)        {            if (T[T[x].fa].fa == to)            {                Rotate(x, T[T[x].fa].son[0] == x);            }            else            {                int y = T[x].fa, z = T[y].fa;                int p = (T[z].son[0] == y);/*y的旋转方向*/                if (T[y].son[p] == x) Rotate(x, !p), Rotate(x, p);                else Rotate(y, p), Rotate(x, p);            }        }        /*to=0,说明x是主根*/        if (to == 0) rt = x;    }    /*按键查找,没找到返回0*/    int find(int key)    {        int x = rt;        while(x && T[x].key != key)        {            x = T[x].son[key > T[x].key];        }        if (x) Spaly(x, 0);/*如果找到,就旋转到根节点下面*/        return x;    }    void insert(int key, int num)    {        if (!rt)        {            T[rt = cnt++] = TreeNode(key, 1, 0, num);        }        else        {            /*y纪录的是x的父节点的编号*/            int x = rt, y = 0;            while(x)            {                y = x;                x = T[x].son[key > T[x].key];            }            /*创建新的节点*/            T[x = cnt++] = TreeNode(key, 1, y, num);            T[y].son[key > T[y].key] = x;            Spaly(x, 0);        }    }    void Delete(int key)    {        int x = find(key);        if (!x) 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)/*x没有左子树*/        {            Spaly(z, 0);            T[z].son[0] = 0;/*x没有左子树,故son[0] = 0*/            PushUp(z);            return ;        }        if (!z)/*x没有右子树*/        {            Spaly(y, 0);            T[y].son[1] = 0;/*x没有右子树,故son[1] = 0*/            PushUp(y);            return ;        }        /*左右子树同时有,先把y移到0下面,在把z移到y下面,注意更新顺序*/        Spaly(y, 0);        Spaly(z, y);        T[z].son[0] = 0;        PushUp(z);        PushUp(y);    }    /*找第p大*/    int GetPth(int 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-= T[T[x].son[0]].size + 1;                x = T[x].son[1];            }else x = T[x].son[0];        }        Spaly(x, 0);        return x;    }}solve;int nCase = 0;int main(){    // freopen("/Users/jamesqi/Desktop/in.txt","r",stdin);    int p, key, num, x;    solve.init();    while(scanf("%d", &p) && p)    {        switch(p)        {            case 1:                /*插入键、值*/                scanf("%d%d", &num, &key);                solve.insert(key, num);                break;            case 2:                /*最大值*/                num = T[solve.rt].size;                x = solve.GetPth(num);                if (x)                {                    printf("%d\n", T[x].num);                    solve.Delete(T[x].key);                }                else                    printf("0\n");                break;            case 3:                /*最小值*/                x = solve.GetPth(1);                if (x)                {                    printf("%d\n", T[x].num);                    solve.Delete(T[x].key);                }                else                     printf("0\n");                break;        }    }    return 0;}
0 0
原创粉丝点击