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;
}

浙公网安备 33010602011771号