斜率优化求调
查看原帖
斜率优化求调
495473
Parsley_楼主2024/8/10 14:16

首先我想验证一下我这个想法可不可以,题解里都是以 2as[i]2as[i] 为斜率维护上凸包,我想以 −2as[i]-2as[i] 维护下凸包不知道可不可以,然后就是这个代码了,一直不对,求救谢谢。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define CHECK cout<<"WALKED"<<endl;
#define ls u<<1
#define rs u<<1|1
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
ll qpow(ll a, ll b, ll mod){ll res = 1;  while (b > 0){if (b & 1) res = res * a % mod;a = a * a % mod;  b >>= 1;  }  return res;}
using namespace std;

const int N = 1e6 + 5;
int n, a, b, c;
ll s[N], f[N], q[N], h , t;

inline ll dx(int i, int j) { return s[i] - s[j];}
inline ll dy(int i, int j) { return (b * s[i] - a * s[i] * s[i] - f[i]) -
									(b * s[j] - a * s[j] * s[j] - f[j]);}

int main()
{
	scanf("%d %d %d %d", &n, &a, &b, &c);
	for (int i = 1; i <= n; i++) {
		scanf("%lld", &s[i]);
		s[i] += s[i - 1];
	}
	for (int i = 2; i <= n ; i++) { // i from 1 or 2
		
		
		
		int now_k = -2 * a * (s[i] - s[i - 1]); // watch out
		
		while (h < t && dy(q[h], q[h + 1]) <= now_k * dx(q[h], q[h + 1]))
			h++;
		
		int j = q[h];
		f[i] = f[j] + a * (s[i] - s[j]) * (s[i] - s[j]) + b * (s[i] - s[j]) + c;
		
		
		while (h < t && dy(q[t], i) * dx(q[t - 1], q[t])  <= dy(q[t - 1], q[t]) * dx(q[t], i))
			t--;
		// t - i, t - 1 - i 
		q[++t] = i;
	}
	printf("%lld\n", f[n]);
	return 0;
}
2024/8/10 14:16
加载中...