UOJ Logo zhouzixuan的博客

博客

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

2015-09-20 22:43:29 By zhouzixuan
【题目描述】:
    一个正整数数列 A[1]…A[n],
    那么 目标是求另一个正整数数列 B[1]…B[n], 使得对于任意的 1≤i<n 有 B[i] ≤B[i+1],
    而且使得 Ans = Max{|A[j]-B[j]|,1≤j≤n}尽量 小。
【题目解法】:
    我们发现只有逆序对才会对答案产生影响
    我们把所有逆序对提到同一高度即可
    显然两个逆序对变成他们的中位数最优
    因此我们取逆序对之差的最大值作为答案
    最后把答案/2即可
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=5000005;
int n; long long a[N],Sa,Sb,Sc,Sd,maxmod,ans,b[N];
inline long long getint()
{
    long long x=0; char c=getchar(); bool flag=false;
    while ((c!='-')&&((c<'0')||(c>'9'))) c=getchar();
    if (c=='-') flag=true,c=getchar();
    while ((c>='0')&&(c<='9')) x=x*10+(long long)(c-'0'),c=getchar();
    if (flag) return -x; else return x;
}
inline long long calc(long long x)
{
    long long nowans=0;
    nowans=(nowans+Sd)%maxmod;
    nowans=(nowans+Sc*x%maxmod)%maxmod;
    nowans=(nowans+Sb*x%maxmod*x%maxmod)%maxmod;
    nowans=(nowans+Sa*x%maxmod*x%maxmod*x%maxmod)%maxmod;
    return nowans;
}
void init()
{
    n=getint(); Sa=getint(); Sb=getint();
    Sc=getint(); Sd=getint(); a[1]=getint(); maxmod=getint();
    for (int i=2; i<=n; i++) a[i]=(calc(a[i-1])+calc(a[i-2]))%maxmod;
}
void solve()
{
    long long maxt=0;
    for (int i=1; i<=n; i++)
    {
        maxt=max(maxt,a[i]);
        ans=max(ans,maxt-a[i]);
    }
    printf("%lld\n",ans/2+ans%2);
}
int main()
{
    init();
    solve();
    return 0;
}

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。