题目描述
给出项数为 n 的整数数列 a1…n。
定义函数 f(i)代表数列中第 i 个元素之后第一个大于 ai 的元素的下标。若不存在,则 f(i)=0。
试求出 f(1…n)。
输入格式
第一行一个正整数 n。
第二行 n 个正整数 a1……n。
输出格式
一行 n个整数f(1……n) 的值。
输入输出样例
输入
5 1 4 2 3 5
输出
2 5 4 5 0
说明/提示
【数据规模与约定】
对于 30% 的数据,n≤100;
对于 60% 的数据,n≤5×10^3 ;
对于 100%的数据,1≤n≤3×10^6,1≤ai≤10^9。
实现思路
第i个元素后比ai大的元素,仅有两种情况,要么是第i+1个元素,要么是比第i+1个元素更大的元素。若a[i+1]就比a[i]大,则f[i]=i+1; 而比第i+1个元素更大的元素可以通过序号为f[i+1]的元素开始往后遍历,不妨将每次遍历的元素序号设为j,则 j 依次取得f[i+1],f[a[f[i+1]]]……,若遍历过程中发现有元素大于a[i],则停止遍历,此时的 j 即为f[i]的值;若遍历到 j 取 0 时仍未发现大于a[i]的元素,则说明f[i]=0。
不难看出f[n]=0,因此我们可从倒数第二个元素开始从后向前遍历,按上述方法依次求出f[n-1],f[n-2]……f[1]。
完整代码
#include<stdio.h>
long n,a[3000001]={0};
int f[3000001]={0};
int main()
{
scanf("%ld",&n);
int i,j;
for(i=1;i<=n;i++){
scanf("%ld",&a[i]);
}
for(i=n-1;i>0;i--){
if(a[i+1]>a[i]) f[i]=i+1; //a[i+1]>a[i]的情况
else{ //a[i+1]<=a[i]的情况
for(j=f[i+1];j!=0;j=f[j]){ //遍历寻找大于a[i]的元素
if(a[j]>a[i]){
f[i]=j; break;
}
}
}
}
for(i=1;i<=n;i++)
printf("%d ",f[i]);
return 0;
}
AC截图