HEOI 2014 南园满地堆轻絮

HEOI 2014 南园满地堆轻絮

洛谷传送门

题目描述

小 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 想要知道对于一首给定的曲子,如何通过提高音调或者降低音调,将它的音调修改的不下降,而且使得修改幅度最大的那个音符的修改幅度尽量小。即如果把一个包含 nn 个音 符的曲子看做是一个正整数数列 A[1] \cdots A[n]A[1]⋯A[n],那么目标是求另一个正整数数列 B[1]…B[n]B[1]…B[n], 使得对于任意的 1≤i<n1≤i<n 有 B[i] ≤B[i+1]B[i]≤B[i+1],而且使得 Ans = Max{|A[j]-B[j]|,1≤j≤n}Ans=Max{∣A[j]−B[j]∣,1≤jn}尽量 小。 小 Z 很快就想清楚了做法,但是鉴于他还忙着写诗,所以这个任务就交给了你。

输入格式

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

每个数据包含 7 个数:n,S_a,S_b,S_c,S_d,A[1],Modn,S**a,S**b,S**c,S**d,A[1],Mod,即共有 n 个音符,第一个音符为 A[1]。

生成规则如下: 定义生成函数 F(x) = S_ax^3 + S_bx^2 + S_cx + S_dF(x)=Sax3+Sbx2+Scx+Sd; 那么给出递推公式 A[i] =( F(A[i-1]) + F(A[i-2]) )%modA[i]=(F(A[i−1])+F(A[i−2]))%mod,此处规定 A[0] = 0A[0]=0. 由于中间过程的数可能会特别大,所以要求每一步与 AA* 中的每个数都对一个给定的数 ModMod 取模。

输出格式

输出一行,包含一个正整数 AnsAns


题解:

结论题。答案就是(最大逆序对的差+1)/2。

证明:假设最大逆序对的下标为\(i,j\),那么对于这个区间,因为它已经是最大的逆序对了,所以不会对这个区间的答案造成影响。

然后对于它两边的区间\((1,i),(j,n)\),同理,因为已经是最大逆序对了,所以这两个区间的最大逆序对不会超过\(i,j\)。也就保证了答案的正确性。

代码:

#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
const int maxn=5e6+6;
int n,sa,sb,sc,sd,mod,maxx,ans;
int a[maxn];
int fun(int x)
{
    int ret=((sa*x%mod*x%mod*x%mod)+(sb*x%mod*x%mod)+(sc*x%mod)+sd%mod)%mod;
    return ret%mod;
}
signed main()
{
    scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&sa,&sb,&sc,&sd,&a[1],&mod);
    for(int i=2;i<=n;i++)
        a[i]=(fun(a[i-1])%mod+fun(a[i-2])%mod)%mod;
    for(int i=1;i<=n;i++)
        if(maxx<=a[i])
            maxx=a[i];
        else
            ans=max(ans,(maxx-a[i]+1)>>1);
    printf("%lld\n",ans);
    return 0;
}
posted @ 2020-11-30 14:24  Seaway-Fu  阅读(103)  评论(0编辑  收藏  举报