您的位置:首页 > 产品设计 > UI/UE

POJ 3481 Double Queue

2015-02-15 03:25 405 查看
题意:

有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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: