ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NOIP模拟41

2021-08-17 06:31:51  阅读:119  来源: 互联网

标签:cnt NOIP read ++ 41 int while ans 模拟


  考场上读错题,直接炸裂。
  题目中说“任一”的意思是优弧与劣弧中随便一个满足条件即可,不是要求都满足要求。
  很明显可以用单调栈。
  常规做法是将环拆开,变成\(2n\)的链,然后直接跑单调栈,会\(T\)。
  题解的做法是将某个最大值放在端点,因为很明显如果你的某个弧上有最大值,那他一定不合法,而将最大值放在一个端点可以避免考虑这种不合法的弧从而减少枚举,降低复杂度。
  最后要注意的是原来是个环,大于或等于\(a[n]\)的一些值也许可以和最大值配对,这些答案要考虑。

Code
#include<bits/stdc++.h>
using namespace std;
namespace STD
{
	#define rr register
	typedef long long ll;
	const int inf=INT_MAX;
	const int N=5e6+4;
	int n;
	int a_[N];
	struct pack
	{int val,num;}a[N];
	int read()
	{
		rr int x_read=0,y_read=1;
		rr char c_read=getchar();
		while(c_read<'0'||c_read>'9')
		{
			if(c_read=='-') y_read=-1;
			c_read=getchar();
		}
		while(c_read<='9'&&c_read>='0')
		{
			x_read=(x_read<<3)+(x_read<<1)+(c_read^48);
			c_read=getchar();
		}
		return x_read*y_read;
	}
	class Stack
	{
		public:
			pack *Top;
			pack s[N];
			Stack(){Top=s;}
			inline pack top(){return *Top;}
			inline void push(pack x){*(++Top)=x;}
			inline void pop(){Top--;}
			inline bool empty(){return Top==s;}
			inline size_t size(){return Top-s;}
	}s;
};
using namespace STD;
int main()
{
	n=read();
	int maxn=-inf,id;
	for(int i=1;i<=n;i++) 
	{
		a_[i]=read();
		if(a_[i]>maxn)
		{
			maxn=a_[i];
			id=i;
		}
	}
	int po=1;
	for(int i=id;i<=n;i++)
		a[po].val=a_[i],a[po++].num=0;
	for(int i=1;i<id;i++)
		a[po].val=a_[i],a[po++].num=0;
	po--;
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		if(s.empty()){a[i].num=1;s.push(a[i]);continue;}
		if(a[i].val==s.top().val)
		{
			a[i].num=s.top().num+1;
			ans+=s.top().num;
			if(s.size()>s.top().num)
				ans++;
			s.push(a[i]);
			continue;
		}
		if(a[i].val<s.top().val)
		{
			a[i].num=1;
			ans++;
			s.push(a[i]);
			continue;
		}
		while(!s.empty()&&s.top().val<a[i].val)
		{
			ans++;
			s.pop();
		}
		if(s.empty()){a[i].num=1;s.push(a[i]);continue;}
		if(a[i].val==s.top().val)
		{
			a[i].num=s.top().num+1;
			ans+=s.top().num;
			if(s.size()>s.top().num)
				ans++;
			s.push(a[i]);
			continue;
		}
		ans++;
		a[i].num=1;
		s.push(a[i]);
	}
	pack *p=s.s+1;
	int cnt=0;
	while(cnt<3&&p<s.Top)
	{
		if(p->val!=(p-1)->val)
			cnt++;
		if(cnt==3) break;
		p++;
	}
	if(cnt==3)
	{
		while(s.Top>=p)
		{
			s.pop();
			ans++;
		}
	}
	else
	{
		if(cnt>1)
		while(s.top().val==a[n].val)
			s.pop(),ans++;
	}
	cout<<ans<<'\n';
}

标签:cnt,NOIP,read,++,41,int,while,ans,模拟
来源: https://www.cnblogs.com/Geek-Kay/p/15150676.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有