P7799 [COCI2015-2016#6] PIANINO

洛谷

首先由于升高还是降低都只受标准音影响。

所以很容易想到将在每一步提高或者降低的次数预处理出来。

为了方便处理,可以将第一项设置为 \(0\),其它都减去原本第一项的值,保留相对关系。

然后就可以通过当前的值除以改变次数,然后可以得到在值为多少时可以到这个点。

但是数值范围很大,不能直接开数组统计。

所以我这边是直接使用了离散化进行处理。

然后要关注一下正负关系和值为 \(0\) 的情况即可。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[1000005],dp[1000005],tmp[1000005],cnt,t[1000005];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=2;i<=n;i++){
		if(a[i]>a[i-1])dp[i]=dp[i-1]+1;
		else if(a[i]<a[i-1])dp[i]=dp[i-1]-1;
		else dp[i]=dp[i-1];
	}
	int tmp2=a[1];
	for(int i=1;i<=n;i++)a[i]-=tmp2;
	for(int i=1;i<=n;i++){
		if(!dp[i])continue;
		if(a[i]>0&&dp[i]<0||a[i]<0&&dp[i]>0)continue;
		if(a[i]%dp[i]!=0)continue;
		tmp[++cnt]=a[i]/dp[i];
	}
	sort(tmp+1,tmp+cnt+1);
	cnt=unique(tmp+1,tmp+cnt+1)-tmp-1;
	int ans=0;
	int s=0,w=0;
	for(int i=1;i<=n;i++){
		if(!dp[i]){
			if(!a[i])ans++;
		}
		else {
			if(a[i]>0&&dp[i]<0||a[i]<0&&dp[i]>0)continue;
			if(a[i]%dp[i]!=0)continue;
			tmp2=lower_bound(tmp+1,tmp+cnt+1,a[i]/dp[i])-tmp;
			t[tmp2]++;
			if(t[tmp2]>s){
				s=t[tmp2];
				w=tmp2;
			}
			else if(t[tmp2]==s&&w>tmp2){
				w=tmp2;
			}
		}
	}
	cout<<s+ans<<endl<<tmp[w];
	return 0;
}

posted @ 2025-10-31 09:25  huhangqi  阅读(10)  评论(0)    收藏  举报
/*
*/