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;
}
posted @ 2019-10-31 21:40  Anticlock  阅读(670)  评论(0编辑  收藏  举报