CodeForces

有一个数列,对于每一个数,求比它小的在他右边距离他最远的那个数和他的距离

用单调队列做,维护单调队列时可采用如下方法,对于每一个数,如果队列中没有数,则加入队列,如果队列头的数比当前数大,则舍弃该数

对于此题,可用两个队列来维护,一个保存值,一个保持位置,每次查询对值进行二分,然后到对应保持位置的队列中求出结果

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-9;
const int N=100000+10,maxn=5000+10,inf=0x3f3f3f3f;

int a[N],ans[N];
vector<int>v,num;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    for(int i=n-1;i>=0;i--)
    {
        if(v.size()==0||v.back()>=a[i])
        {
            v.push_back(a[i]);
            num.push_back(i);
            ans[i]=-1;
        }
        else
        {
            int j=(lower_bound(v.rbegin(),v.rend(),a[i])-v.rbegin());
            j=(int)v.size()-j;
            ans[i]=num[j]-i-1;
        }
       /* for(int j=v.size()-1;j>=0;j--)cout<<v[j]<<" ";
        cout<<endl;*/
    }
    for(int i=0;i<n;i++)
        cout<<ans[i]<<(i==n-1?'
':' ');
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/acjiumeng/p/7157708.html