Codeforces 5E Bindian Signalizing

题意:有n座山围成一个圈,找出两座山,他们之间形成的两段圆弧任意一段中没有高于它们两个的山那么count++;

统计有多少不同对这样的组合;

思路:看别人的题解 ,先将环拆成链,从最高的山那里断开,比如5,3,7,1,4,可以断开为 7,1,4,5,3,7 在最后要加上一个最大值

然后统计每个点左边第一个大于它的山的位置和右边第一个大于它的山的位置,对于相同高度的,只考虑右边就可以(避免重复);

l[i] 存左边,r[i]存右边,s[i]记录相同的个数;

对于每个山,ans先加上s[i],如果此时l[i]==0&&r[i]==n说明左右是同一个山,ans+=1;否则不是同一个山ans+=2;

但是复杂度有点难以计算,玄学吧;

AC代码(其实是参考别人的)

#include <iostream>
#include <string.h>
#include <algorithm>
#define STD std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int maxn=1e6+10;
int a[maxn],b[maxn],l[maxn],r[maxn],s[maxn];
using namespace std;
int main()
{
	STD;
	int n,maxn,po;
	cin>>n;
	for (int i=0;i<n;i++)
		cin>>a[i];
	maxn=a[0];
	po=0;
	for (int i=1;i<n;i++)
	{
		if (a[i]>maxn)
		{
			maxn=a[i];
			po=i;
		}
	}
	for (int i=0;i<n;i++)
		b[i]=a[(po+i)%n];
	b[n]=b[0];
	s[n]=0;
	for (int i=n-1;i>=0;i--)
	{
		r[i]=i+1;
		while (r[i]<n&&b[i]>b[r[i]])
			r[i]=r[r[i]];
		while (r[i]<n&&b[i]==b[r[i]])
		{
			s[i]=s[r[i]]+1;
			r[i]=r[r[i]];	
		}	
	}	
	l[0]=0;
	for (int i=1;i<n;i++)
	{
		l[i]=i-1;
		while (l[i]>0&&b[i]>=b[l[i]])
			l[i]=l[l[i]];
	}
	long long ans=0;
	for (int i=0;i<n;i++)
	{
		ans+=s[i];
		if (b[i]<b[0])
		{
			if (l[i]==0&&r[i]==n)
				ans+=1;
			else
				ans+=2;
		}
	}
	cout<<ans<<endl;
	return 0;
} 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值