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

【传送门:BZOJ3613


简要题意:

  给出一个长度为n的A序列,可以使序列里的数增加或减小一个数,使得整个序列呈不下降序列

  设B数组为最后的不下降序列

  求出最小的ans=Max{|A[j]-B[j]|,1≤j≤n}


题解:

  水题

  直接二分改变大小,然后判断就可以了

  输入的时候取mod要勤奋一点


参考代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL Mod;
LL a[5100000],sa,sb,sc,sd;
LL F(LL x)
{
    x=x%Mod;
    return (((sa*((x%Mod*x%Mod*x%Mod)%Mod))%Mod+(sb*((x%Mod*x%Mod)%Mod))%Mod)%Mod+sc%Mod*x%Mod+sd%Mod)%Mod;
}
int n;
LL L[5100000],R[5100000];
bool check(LL d)
{
    for(int i=1;i<=n;i++) L[i]=max(1LL,a[i]-d),R[i]=a[i]+d;
    LL ll=L[1],rr=R[1];
    for(int i=2;i<=n;i++)
    {
        if(ll>R[i]) return false;
        ll=max(ll,L[i]);
    }
    return true;
}
int main()
{
    scanf("%d%lld%lld%lld%lld%lld%lld",&n,&sa,&sb,&sc,&sd,&a[1],&Mod);
    sa%=Mod;sb%=Mod;sc%=Mod;sd%=Mod;
    a[0]=0;
    for(int i=2;i<=n;i++) a[i]=(F(a[i-1])+F(a[i-2]))%Mod;
    LL l=0,r=1LL<<63-1,ans=0;
    while(l<=r)
    {
        LL mid=(l+r)/2;
        if(check(mid)==true)
        {
            ans=mid;
            r=mid-1;
        }
        else l=mid+1;
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2018-04-12 15:38  Star_Feel  阅读(102)  评论(0编辑  收藏  举报