Description
Solution
维护最大值的最小值,试试二分(+)贪心的套路,发现可以
二分(x),初始(k=-INF),使后一个数在比前一个数大的情况下尽量小,成为新的(k),如果后一个数(+x)仍然大于(k),则(return) (false)
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
#define mid ((l + r) >> 1)
#define INF 0x7fffffff
#define MAXN 5000010
ll n, Sa, Sb, Sc, Sd, MOD, l, r, ans, h;
ll a[MAXN];
inline ll read() {
ll s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
inline ll f(ll x) {
return (((Sa * x % MOD * x % MOD * x % MOD + Sb * x % MOD * x % MOD) + Sc * x) % MOD + Sd) % MOD;
}
inline bool check(ll x) {
h = -INF;
for (register ll i = 1; i <= n; i++) {
if (h > a[i] + x) return false;
h = max(h, a[i] - x);
}
return true;
}
int main() {
n = read(), Sa = read(), Sb = read(), Sc = read(), Sd = read(), a[1] = read(), MOD = read();
for (register ll i = 2; i <= n; i++)
a[i] = (f(a[i - 1]) + f(a[i - 2])) % MOD;
l = 0, r = MOD;
while (l <= r) {
if (check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%lld", ans);
return 0;
}