题意:
给一个序列,对于第i个数字a[i],在右边找到一个比它小的数,并且最靠右的位置k,输出k-i-1,如果一个都找不到,输出-1。对于序列的每个元素都要输出。
思路:
从最后一个数开始处理,若该数比队列中最后一个都小,则是-1,并加入队尾,否则就对队列中的数进行二分
PS:想到单调队列中的数组下标具有单调性,然后可以进行二分是解题的关键。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int a[maxn], ans[maxn], q[maxn], x[maxn];
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
int cnt = 0;
for(int i = n; i >= 1; i--)
{
if(a[i] <= x[cnt-1] || cnt == 0)
{
x[cnt] = a[i];
q[cnt++] = i;
ans[i] = -1;
}
else
{
int left = 0, right = cnt - 1, mid, pos;
while(left <= right)
{
mid = (left + right) >> 1;
if(x[mid] < a[i])
{
pos = mid;
right = mid - 1;
}
else
left = mid + 1;
}
ans[i] = q[pos] - i - 1;
}
}
for(int i = 1; i <= n; i++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
return 0;
}