【传送门: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 ",ans); return 0; }