南园满地堆轻絮

[HEOI2014]南园满地堆轻絮

https://ac.nowcoder.com/acm/problem/20012

题意看了好久才明白(:з」∠)
给一个序列a[],要求一个不会递减的数组b[],并且b要满足|a[i]-b[i]|尽量小

用二分找a与b的差值
如果差值是x
如果a[i]>=b[i-1],那b[i]=max(b[i-1],a[i]-x)
如果a[i]<b[i-1]-x,那差值x就不成立
其他情况就可以让b[i]=b[i-1]

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
ll n,m,sa,sb,sc,sd,mod,a[5000005],b;
ll fun(ll x)
{
    ll a=(sa*x%mod)*x%mod *x%mod,b=sb*x%mod*x%mod,c=sc*x%mod,d=sd%mod;
    return ((((a+b)%mod)+c)%mod+d)%mod;
}
int check(int x)
{
    b=a[1]-x;
    for(int i=2;i<=n;++i)
        if(a[i]>=b)
            b=max(b,a[i]-x);
        else if(a[i]<b-x)
            return 0;
    return 1;
}
int main ()
{
    ll T,i,t,j,k,p,sum=0;
    cin>>n>>sa>>sb>>sc>>sd>>a[1]>>mod;
    for(i=2;i<=n;++i)
        a[i]=(fun(a[i-1])+fun(a[i-2]))%mod;
    ll l=0,r=inf,ans=-1;
    while(l<=r){
        ll mid=(l+r)/2;
        if(check(mid))
            r=mid-1,ans=mid;
        else l=mid+1;
    }
    cout<<ans<<endl;
    return 0;
}
全部评论

相关推荐

球球别再泡了:坏,我单9要了14
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务