联赛模拟测试24 D. 你相信引力吗 单调栈

题目描述



分析

因为跨过最大值的区间一定是合法的,所以我们人为地把最大值放在最左边
我们要统计的就是在最大值右边单调不降的序列,可以用单调栈维护
需要特殊处理相同的情况

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rg register
inline int read(){
	rg int x=0,fh=1;
	rg char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') fh=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*fh;
}
const int maxn=1e7+5;
int n,a[maxn],sta[maxn],tp,be,ed,mmax,cnt[maxn];
long long ans;
int main(){
	n=read();
	for(rg int i=1;i<=n;i++){
		a[i]=read();
		a[n+i]=a[i];
		if(a[i]>mmax){
			mmax=a[i];
			be=i;
		}
	}
	ed=be+n-1;
	for(rg int i=be;i<=ed;i++){
		while(tp && sta[tp]<a[i]){
			ans++;
			tp--;
		}
		if(sta[tp]>a[i]){
			ans++;
		} else {
			if(a[i]!=mmax)ans+=cnt[tp]+1;
			else ans+=cnt[tp];
		}
		sta[++tp]=a[i];
		if(a[i]==sta[tp-1]) cnt[tp]=cnt[tp-1]+1;
		else cnt[tp]=1;
	}
	while(tp>2){
		if(sta[tp]==sta[2]) break;
		ans++;
		tp--;
	}
	printf("%lld
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/liuchanglc/p/13879541.html