bzoj3613: [Heoi2014]南园满地堆轻絮

题意

即如果把一个包含 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值