CodeForces - 91B Queue (单调栈+二分)

题目链接:https://codeforces.com/problemset/problem/91/B

题目大意:给你一个倒置的序列,让你找到每个数的前面离他最远的那个数和它中间隔了多少个数,如果没有,输出-1

Examples

Input
6
10 8 5 3 50 45
Output
2 1 0 -1 0 -1 
Input
7
10 4 6 3 2 8 15
Output
4 2 1 0 -1 -1 -1 
Input
5
10 3 1 10 11
Output
1 0 -1 -1 -1 

emmm,没什么好说的,用单调栈维护一个下降序列,对于小于栈顶的直接放进去,等于的要舍掉,然后对于大于栈顶的,我们二分查找左边第一个小于等于他的数,直接用lower_bound就好了。lower_bound对于递减序列的查找,是找到最左边的小于等于它的数,如果有:18  18  6  5,它找的到的是位置1,所以我们才要舍弃掉后面等于的数。

以下是AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; 

const int mac=1e5+10;
const int inf=1e9+10;

int a[mac],ans[mac],q[mac],qs[mac];

bool cmp(int x,int y){return x>y;}

int main(int argc, char const *argv[])
{
    int n;
    scanf ("%d",&n);
    for (int i=1; i<=n; i++)
        scanf ("%d",&a[i]);
    reverse(a+1,a+1+n);
    int head=1,tail=0;
    for (int i=1; i<=n; i++){
        if (head>tail || a[i]<=qs[tail]) {
            if (a[i]==qs[tail]) {ans[i]=-1; continue;}
            qs[++tail]=a[i];
            q[tail]=i; 
            ans[i]=-1; continue;
        }
        if (a[i]>qs[1]) {ans[i]=i-2;continue;}
        int it=lower_bound(qs+1,qs+1+tail,a[i],cmp)-qs;//找到的是最左边小于等于他的数
        if (qs[it]==a[i]) ans[i]=i-q[it+1]-1;
        else ans[i]=i-q[it]-1;
    }
    reverse(ans+1,ans+1+n);
    for (int i=1; i<=n; i++)
        printf("%d%c",ans[i],i==n?'\n':' ');
    return 0;
}

 

posted @ 2020-07-09 12:22  lonely_wind  阅读(285)  评论(0编辑  收藏  举报