保证我这种蒟蒻考试时遇到这种题是做不出来的 想了好久qwq 原题戳这儿 N=1e6 显然暴力枚举右边第一个是会TLE的,怎么办呢 发现问题:多次重复枚举不优解 怎么解决呢: 设kjl[i]为i的答案(看到的人) 发现如果a[i]比a[j]大,(j>i),则a[j]到a[kjl[i-1]]的答案都小于a[i],(因为取这个范围内的一个数k,a[i]>a[j]>a[k]) 所以可以直接跳到a[kjl[i]]枚举,如果还小于a[i]则跳到a[kjl[kjl[i]],一直跳着找就可以了 关于复杂度:o(n)级别(与单调栈差不多)
代码(有详细注解):
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int h[N],kjl[N],n;//看巨佬简写kjl int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&h[i]); kjl[i]=i+1;//最开始设成仰望右边的人 } kjl[n]=0;//如果递推到0说明右边人都比你小,你最巨 for(int i=n-1;i>=1;i--){//倒着推,因为你递推要用右边的kjl数组 while(kjl[i]){//见上 if(h[kjl[i]]>h[i])break;//找到更巨佬的人 kjl[i]=kjl[kjl[i]];//递归寻找 } //如果没有找到kjl[i]=0 } for(int i=1;i<=n;i++)printf("%d\n",kjl[i]);//顺序输出 return 0; }当然,此题也可以用单调队列/单调栈/平衡树等玄学数据结构维护,虽然我也会,但是毕竟越简单的方法做出来就越巧妙