POJ 3481 Double Queue

题意:

有3种操作:

1 K P,把权值为K,优先级P的数据存在查询的表里;

2,返回优先级最大的权值,并删除该项

3,返回优先级最小的权值,并删除该项

思路:

刚学了SBT,用来练手了,我用map存储了优先级对应的答案,700+mm,感觉时间太长了。。。。。。

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include<map>
using namespace std;
const int MAXN=111111;
struct SBT
{
    int left,right,size,key;
    int val;
    void Init()
    {
        left=right=0;
        size=1;
    }
}tree[MAXN];
int tot,root;
void left_rotate(int &x)//左旋
{
    int y=tree[x].right;
    tree[x].right=tree[y].left;
    tree[y].left=x;
    tree[y].size=tree[x].size;
    tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
    x=y;
}
void right_rotate(int &x)//右旋
{
    int y=tree[x].left;
    tree[x].left=tree[y].right;
    tree[y].right=x;
    tree[y].size=tree[x].size;
    tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
    x=y;
}
void maintain(int &x,int flag)
{
    if(flag==0)
    {
        if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size)
           right_rotate(x);
        else if(tree[tree[tree[x].left].right].size > tree[tree[x].right].size)
            left_rotate(tree[x].left),right_rotate(x);
        else return;
    }
    else
    {
        if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size)
            left_rotate(x);
        else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size)
            right_rotate(tree[x].right),left_rotate(x);
        else return;
    }
    maintain(tree[x].left,0);
    maintain(tree[x].right,1);
    maintain(x,0);
    maintain(x,1);
}
//插入元素,相同元素放在右子树中
void insert(int &x,int key)
{
    if(x==0)
    {
        x=++tot;
        tree[x].Init();
        tree[x].key=key;
    }
    else
    {
        tree[x].size++;
        if(key<tree[x].key)insert(tree[x].left,key);
        else insert(tree[x].right,key);
        maintain(x,key>=tree[x].key);
    }
}
//删除key值的元素
int del(int &x,int key)
{
    if(!x)return 0;
    tree[x].size--;
    if(key==tree[x].key || (key<tree[x].key&&tree[x].left==0)
       || (key>tree[x].key&&tree[x].right==0))
    {
        if(tree[x].left && tree[x].right)
        {
            int p=del(tree[x].left,key+1);
            tree[x].key=tree[p].key;
            return p;
        }
        else
        {
            int p=x;
            x=tree[x].left+tree[x].right;
            return p;
        }
    }
    else return del(key<tree[x].key?tree[x].left:tree[x].right,key);
}

//取最大值
//返回最大值的节点编号
int Get_Max(int x)
{
    while(tree[x].right)x=tree[x].right;
    return x;
}
//取最小值
//返回最小值的节点编号
int Get_Min(int x)
{
    while(tree[x].left)x=tree[x].left;
    return x;
}

int main()
{
	root = tot = 0;
	int k,aa,bb;
	map<int,int> ans;
	while(scanf("%d",&k),k)
	{
		if(k==2)
		{
			if(root==0)
			printf("0\n");
			else
			{
				int t=tree[Get_Max(root)].key;
				printf("%d\n",ans[t]);
				del(root,t);
			}
		}
		if(k==3)
		{
			if(root==0)
			printf("0\n");
			else
			{
				int t=tree[Get_Min(root)].key;
				printf("%d\n",ans[t]);
				del(root,t);
			}
		}
		if(k==1)
		{
			scanf("%d%d",&aa,&bb);
			ans[bb]=aa;
			//printf("%d\n",ans[bb]);
			insert(root,bb);
		}
	} 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值