这个题想了好久才做出来,本来感觉要维护一个区间最值的数据结构,然后每次搜索的时候借助那个区间最值帮助剪枝,后来发现好多人都过了,我就觉得这题应该不用那么麻烦,果然,想了一会,维护一个单调栈,贪心就可以解决了。
从右往左往栈里放点,从栈底到栈顶必须单调递减,如果有大元素值放入,那么把它底下的所有小于等于它的元素全部pop掉,再往里放,这样子O(n)解决。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <bits/stdc++.h>
using namespace std;
struct node{
int p,v;
node(){}
node(int P,int V){
p=P;
v=V;
}
};
node A[100009];
int ans[100009];
int main(){
int N;
cin>>N;
for(int i=0;i<N;i++){
int a;
scanf("%d",&a);
A[i]=node(i,a);
}
node S[100009];
int Size=0;
for(int i=N-1;i>=0;i--){
if(Size==0){
S[Size++]=A[i];
ans[i]=-1;
continue;
}
if(A[i].v<S[Size-1].v){
ans[i]=S[Size-1].p-i;
S[Size++]=A[i];
}
else{
while(Size>0){
if(S[Size-1].v<=A[i].v){
Size--;
}
else break;
}
i++;
}
}
for(int i=0;i<N;i++){
printf("%d\n",ans[i]);
}
return 0;
}
//
// _oo0oo_
// o8888888o
// 88" . "88
// (| -_- |)
// 0\ = /0
// ___/`---'\___
// .' \\| |// '.
// / \\||| : |||// \
// / _||||| -:- |||||- \
// | | \\\ - /// | |
// | \_| ''\---/'' |_/ |
// \ .-\__ '-' ___/-. /
// ___'. .' /--.--\ `. .'___
// ."" '< `.___\_<|>_/___.' >' "".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `_. \_ __\ /__ _/ .-` / /
// =====`-.____`.___ \_____/___.-`___.-'=====
// `=---='
//
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 佛祖保佑 永无BUG
//
//
//