[BZOJ]3613: [Heoi2014]南园满地堆轻絮 乱搞+简要证明

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], 使得对于任意的 1≤i

题解:

看过网上其他题解的都应该知道,答案是将差值最大的逆序对变为同一个数的代价,至于证明,我好像并没有看到,都说自己YY一下就行了,我是这么YY的:对于一对差值最大的逆序对(a,b),a、b之间的数显然是大于等于b小于等于a的,那么这个a~b的区间显然可以全部变为同样的一个数。然后对于左右两个区间,如果不能变为a~b区间的这个数,就可以用类似递归的方式处理。

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int Maxn=5000010;
LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
LL n,sa,sb,sc,sd,mod,a[Maxn],mn[Maxn];
LL f(LL x){return (sa*x%mod*x%mod*x%mod+sb*x%mod*x%mod+sc*x%mod+sd)%mod;}
int main()
{
    n=read();sa=read();sb=read();sc=read();sd=read();a[1]=read();mod=read();
    a[0]=0;for(int i=2;i<=n;i++)a[i]=(f(a[i-1])+f(a[i-2]))%mod;
    mn[n]=a[n];for(int i=n-1;i;i--)mn[i]=min(mn[i+1],a[i]);
    LL n1,n2,w=0;
    for(int i=1;i<=n;i++)
    if(a[i]-mn[i]>w)w=a[i]-mn[i],n1=a[i],n2=mn[i];
    printf("%lld",n1-(n1+n2)/2);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值