题意
即如果把一个包含 n 个音 符的曲子看做是一个正整数数列 A[1]…A[n],
那么 目标是求另一个正整数数列 B[1]…B[n], 使得对于任意的 1≤i
<
<script type="math/tex" id="MathJax-Element-1"><</script>n 有 B[i] ≤B[i+1],
而且使得 Ans = Max{|A[j]-B[j]|,1≤j≤n}尽量 小。
题解
这题我想了好一会啊。。
终于给想出来了。。
一开始想了很多乱七八糟的东西
比如说我第一反应就是二分答案,然后判断嘛,就直接扫过去,每一次维护两个值L和R,表示这个数能选的范围有这些,然后取下交集什么的
然后感觉这样会T
于是继续想
最后发现,其实我们只需要找到一个点,使得他们左边的最大减右边的最小的差值差值/2(向上取整)最大就好了
正确性显然?
CODE
#include<cstdio>
typedef long long LL;
const LL N=5000005;
LL n,sa,sb,sc,sd,a[N],mod;
LL maxx[N],minn[N];//到这个点位置的最大值 最小值
LL F (LL x)
{
return (((sa*x%mod*x%mod*x%mod + sb*x%mod*x%mod)%mod+ sc*x%mod)%mod + sd)%mod;
}
int main()
{
scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&sa,&sb,&sc,&sd,&a[1],&mod);
a[0]=0;
for (LL i=2;i<=n;i++) a[i]=(F(a[i-1])+F(a[i-2]))%mod;
maxx[0]=-mod;
for (LL u=1;u<=n;u++)
{
maxx[u]=maxx[u-1];
if (a[u]>maxx[u]) maxx[u]=a[u];
}
minn[n+1]=mod;
for (LL u=n;u>=1;u--)
{
minn[u]=minn[u+1];
if (a[u]<minn[u]) minn[u]=a[u];
}
LL ans=0;
for (LL u=1;u<=n;u++)
{
if ((maxx[u]-minn[u]+1)/2>ans) ans=(maxx[u]-minn[u]+1)/2;
}
printf("%lld\n",ans);
return 0;
}