(优先队列)CodeForces 91B Queue

这题感觉其他博客大几十行的做法好麻烦啊,啥单调栈上二分和线段树,没必要这么麻烦

 这题题意就是找离第i个数最远且小于a[i]的数在哪,这直接上优先队列,把每个数和它的位置先存到优先队列里,优先队列大的在顶端,然后从后往前找,如果队列顶端的数比a[i]大,那a[i]就是和它配对的数,然后弹出队列顶,(如果这个队列顶端的数位置在i后面,那说明没有数可以和它匹配,那它的值设成-1,然后直接跳过它)重复操作指导队列顶的数小于等于a[i]

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 5050000
#include<queue>
struct node
{
    ll x,id;
    friend bool operator < (node a,node b)
    {
        return a.x<b.x;
    }
};
ll a[maxn],ans[maxn];
priority_queue<node>q;
int main()
{
    ll n,top=0;
    scanf("%lld",&n);
    memset(ans,-1,sizeof(ans));
    for(ll i=1;i<=n;i++) scanf("%lld",&a[i]),q.push({a[i],i});
    for(ll i=n;i>=1;i--)
    {
        while(!q.empty()&&a[i]<q.top().x)
        {
            if(q.top().id>i)
            {
                q.pop();continue;
            }
            ans[q.top().id]=i-q.top().id-1;
            q.pop();
        }
    }
    for(ll i=1;i<=n;i++)
    {
        printf("%lld",ans[i]);
        printf("%c",i==n?'\n':' ');
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43497140/article/details/107500782