分析
作为一名OIer,当看到最大值最小时
一定可以想到二分答案
所以可以顺着这个思路往下
由于最后需要的结果是单调不下降的
所以我们可以考虑贪心
设当前二分答案为Temp
- 若当前在
,若
那么可以直接
break掉,因为无解return false - 若当前
那么
A[i]=min(A[i-1],A[i]+Temp) else可得A[i]=max(A[i]-Temp,A[i-1])
进而就OKay了。。。
代码
//P4105
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define LL long long
#define Lowbit(X) (X&(-X))
#define Lson (X<<1)
#define Rson (X<<1|1)
#define Cl(X,Y) memset((X),(Y),sizeof(X))
#define FOR(i,A,B) for(LL i=A;i<=B;i++)
#define BOR(i,A,B) for(LL i=A;i>=B;i--)
#define FOR_SIDE(i,A) for(LL i=Head[A];i;i=Next[i])
#define INF 0x7fffffff
using namespace std;
const LL MAXN=5e6+10;
LL Total,A,B,C,D,Num[MAXN],MOD,F[MAXN];
LL Ans,Cop[MAXN];
inline void File() {
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
inline LL Function(LL New) {
return (New*New%MOD*New%MOD*A%MOD+New*New%MOD*B%MOD+New*C%MOD+D)%MOD;
}
inline bool Check(LL Temp) {
bool Vis=true;
FOR(i,1,Total) {
if(Cop[i]+Temp<Cop[i-1]) { Vis=false; break; }
if(Cop[i]<=Cop[i-1]) Cop[i]=min(Cop[i-1],Cop[i]+Temp);
else Cop[i]=max(Cop[i]-Temp,Cop[i-1]);
}
return Vis;
}
int main() {
//File();
scanf("%lld",&Total);
scanf("%lld %lld %lld %lld",&A,&B,&C,&D);
scanf("%lld %lld",&Num[1],&MOD);
F[0]=Function(Num[0]);
F[1]=Function(Num[1]);
FOR(i,2,Total) {
Num[i]=(F[i-1]+F[i-2])%MOD;
F[i]=Function(Num[i]);
}
LL L=0,R=MOD;
while(L<=R) {
FOR(i,1,Total) Cop[i]=Num[i];
Cop[0]=-INF;
LL Mid=(L+R)>>1;
if(Check(Mid)) R=Mid-1,Ans=Mid;
else L=Mid+1;
}
printf("%lld\n",Ans);
//fclose(stdin); fclose(stdout);
// system("pause");
return 0;
} 
京公网安备 11010502036488号