heap
sjtu1216
Description
使用最小化堆实现一个整型的优先队列,实现下列功能:
insert x,将优先级值为x的元素入队
find x,找出优先级值大于x的最小的元素,输出其下标。如果有多个元素优先级值相同输出下标最小的那个。
DECREASE i v,将第i个节点的优先级值减少v。
Input Format
第一行含有一个正整数M(1<=M<=20000),代表总的操作数。
以下M行,每行一个操作。
Output Format
对于每个find操作,输出一个下标。回车分隔。
Sample Input1
9
insert 5
insert 6
insert 7
find 5
find 6
decrease 1 3
decrease 2 5
decrease 3 5
find 1
Sample Output1
2
3
2
Limit
输入数据保证合法
find操作只要求时间复杂度O(n),其他操作要求O(logn)
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<climits>
#define maxn 20050
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x)
{
x=0;
T f=1;
char c=getchar();
for(; c<'0'||c>'9'; c=getchar()) if(c=='-') f=-1;
for(; c>='0'&&c<='9'; c=getchar()) x=(x<<1)+(x<<3)+(c&15);
}
template<typename T>inline void print(T x)
{
if(x<0) putchar('-'),x*=-1;
if(x>=10) print(x/10);
putchar(x%10+'0');
}
struct Heap //用最小堆实现优先队列
{
int size,queue[maxn];
Heap()
{
size=0;
for(int i=0;i<maxn;i++)
queue[i]=0;
}
void shift_up(int i) //上放
{
while(i>1)
{
if(queue[i]<queue[i>>1])
{
int temp=queue[i];
queue[i]=queue[i>>1];
queue[i>>1]=temp;
}
i>>=1;
}
}
void shift_down(int i) //下方
{
while((i<<1)<=size)
{
int next=i<<1;
if(next<size && queue[next+1]<queue[next])
next++;
if(queue[i]>queue[next])
{
int temp=queue[i];
queue[i]=queue[next];
queue[next]=temp;
i=next;
}
else return ;
}
}
void push(int x)
{
queue[++size]=x;
shift_up(size);
}
void pop() //出队是将首元素与末尾元素交换,再下放
{
int temp=queue[1];
queue[1]=queue[size];
queue[size]=temp;
size--;
shift_down(1);
}
int top(){return queue[1];} //取首元素
bool empty(){return size;} //判空
int Find(int a)
{
int minn=INT_MAX,mini=INT_MAX; //注意初始的时候不要太小, 头文件<climits>
for(int i=0;i<=size;i++) //开始初始为99999,结果wa
{
if(queue[i]>a)
{
if(minn>queue[i])
{
minn=queue[i];
mini=i;
}
}
}
return mini;
}
void decrease(int a,int b)
{
queue[a]-=b;
shift_up(a);
}
};
int main()
{
// std::ios::sync_with_stdio(false);
// std::cin.tie(0);
Heap Q;
int m,a,b;
string s;
read(m);
while(m--)
{
cin>>s;
//cout<<s<<endl;
if(s=="insert")
{
read(a);
Q.push(a);
}
else if(s=="find")
{
read(a);
print(Q.Find(a));
puts("");
}
else
{
read(a);
read(b);
Q.decrease(a,b);
}
}
return 0;
}