题目链接: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?' ':' '); return 0; }