Luogu P4105 [HEOI2014]南园满地堆轻絮

最小化最大值,一眼就能看出来要二分。

我们先通过题目中花里胡哨的方法构造出数据,然后因为题目中修改次数无限,随意修改,我们只要求修改差值的最大值,也就是说我们只需要维护最大值即可。我们只要找到差值最大的逆序对,答案就是最大的逆序对的一半。因为作为逆序对,前面的大于后面,差值最大的两个最终必须都要相等(因为要求最后的序列非严格单调递增,可以相等),那么我们不论是高的降低,还是低的增加,需要改的都是这个差值,肯定是一半最优。
这样我们就可以 O ( n ) O(n) O(n)解决。

#include
#include
#include
#include

using namespace std;
typedef long long ll;
const int N=5e6+10;
int n;
ll a[N];
ll maxx;
int sa, sb, sc, sd;
ll mod;
ll res;
ll f(ll x){
    return (sa * x % mod * x % mod * x % mod + sb * x % mod * x % mod + sc * x % mod + sd) % mod;
}
int main(){
	cin >> n>> sa >> sb >> sc >> sd >> a[1] >> mod;
	maxx = a[1];
	for(int i = 2;i <= n;i ++){
		a[i] = (f(a[i-1]) + f(a[i-2])) % mod;
		res = max(res, maxx - a[i]);
		maxx = max(maxx, a[i]);
	}
	cout << (res + 1) / 2;
	return 0;
}

当然我们也可以用二分解答:

你可能感兴趣的:(#,二分法,三分法,【死亡思维题】)