洛谷P5788 单调栈

题目描述

给出项数为 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截图 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值