【BZOJ 3613】 [Heoi2014]南园满地堆轻絮

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

Time Limit: 50 Sec Memory Limit: 256 MB
Submit: 167 Solved: 109
[Submit][Status][Discuss]
Description

小 Z 是 ZRP(Zombies’ Republic of Poetry,僵尸诗歌共和国)的一名诗歌爱好者,最近 他研究起了诗词音律的问题。
在过去,诗词是需要编成曲子唱出来的,比如下面这首《菩萨蛮》,唱出来的话其对应 的音符就是这样的:
南 园 满 地 堆 轻 絮, 愁 闻 一 霎 清 明 雨
1 1 5 5 6 6 5 4 4 3 3 2 2 1
因而可以发现,“1 1 5 5 6 6 5 4 4 3 3 2 2 1”这串音符就成为了研究音律的关键。
小 Z 翻阅了众多史料发现,过去的一首曲子的音调是不下降的
小 Z 想要知道对于一首给定的曲子,如何通过提高音调或者降低音调,将它的音调修改 的不下降,
而且使得修改幅度最大的那个音符的修改幅度尽量小。
即如果把一个包含 n 个音 符的曲子看做是一个正整数数列 A[1]…A[n],
那么 目标是求另一个正整数数列 B[1]…B[n], 使得对于任意的 1i<n 有 B[i] ≤B[i+1],
而且使得 Ans = Max{|A[j]-B[j]|,1≤j≤n}尽量 小。 小 Z 很快就想清楚了做法,但是鉴于他还忙着写诗,
所以这个任务就交给了你。
Input

由于数据规模可能较大,因此采用如下方式生成数据。

每个数据包含 6 个数:n,Sa,Sb,Sc,Sd,A[1],Mod,意为共有 n 个音符,第一个音符为 A[1]。
生成规则如下: 定义生成函数 F(x) = Sa*x^3 + Sb*x^2 + Sc*x + Sd;
那么给出递推公式 A[i] = F(A[i-1]) + F(A[i-2]),此处规定 A[0] = 0.
由于中间过程的数可能会特别大,所以要求每一步与 A 中的每个数都对一个给定的数 Mod 取模。
Output

输出一行,包含一个正整数 Ans。

Sample Input

3 815 6901 3839 178 199 10007
Sample Output

1334
HINT

n≤5000000

对于 100%的数据, Sa,Sb,Sc,Sd,A[1] ≤10000, Mod≤1000000007

样例中生成的数列为:

199 4568 1901,此时将 4568 修改为 3234,1901 也修改为 3234 即可,代价为 1334。
Source

鸣谢佚名上传

二分。

二分这个最大值,如何判断值 m 是否成立?

从1到n判断,使得当前满足条件的值pre尽可能小,如果 a[i+1]+m 还小于 pre ,这个 m <script id="MathJax-Element-6" type="math/tex">m</script>值一定不成立。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#define LL long long
using namespace std;
int n,a[5000005],mod;
LL sa,sb,sc,sd;
int F(LL x)
{
    return (x*x%mod*x%mod*sa%mod+sb*x%mod*x%mod+sc*x%mod+sd)%mod;
}
int ok(int x)
{
    int pre=a[1]-x;
    for (int i=2;i<=n;i++)
    {
        if (a[i]+x>=pre)
        {
            if (pre<a[i]-x) pre=a[i]-x;
        }
        else return 0;
    }
    return 1;
}
int main()
{
    cin>>n>>sa>>sb>>sc>>sd>>a[1]>>mod;
    a[0]=0;
    for (int i=2;i<=n;i++)
        a[i]=(int)((F(a[i-1])+F(a[i-2]))%mod+mod)%mod;
    int ans,l=0,r=mod+5;
    while(l<=r)
    {
        int m=(l+r)>>1;
        if (ok(m)) ans=m,r=m-1;
        else l=m+1;
    }
    cout<<ans<<endl;
    return 0;
}

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值