0pts求调-斜率优化
查看原帖
0pts求调-斜率优化
768270
__why楼主2024/11/10 16:37

rt,样例也调不出来

#include<bits/stdc++.h>
#define int long long
const int maxn = 1e6+5;
using namespace std;
int n, m;
struct point {
	long long x, y;
	long long idx;
	point(long long x = 0, long long y = 0, long long idx = 0): x(x), y(y), idx(idx) {};
	point operator -(const point &oth) const {
		return point(x - oth.x, y - oth.y);
	}
	long long operator / (const point &oth) const {
		return x*oth.y - oth.x*y;
	}
};
int a[maxn];
int sum[maxn];
int dp[maxn];
signed main() {
	ios::sync_with_stdio(0);
	cin.tie();
	cin >> n >> m;
	m = m + 1;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		sum[i] = sum[i - 1] + a[i];
	}
	for(int i = 1;i<=n;i++)sum[i] += i;
	vector<point>st;
	for(int i = 1;i<=n;i++){
		dp[i] = sum[i]*sum[i]+m*m-2*sum[i]*m;
	}
	st.push_back(point(0, 0, 0));
	int t = 0;
	for (int i = 1; i <= n; i++) {
		auto k = 2 * sum[i];
		//计算f[i]的值
		while (t + 1 < st.size() && (st[t + 1] - st[t]) / point(1, k) > 0)++t;
		//y:dp[j]+sum[j]*sum[j] dp[j]+sum[j]*sum[j]-2*m*sum[j];
		//x:sum[j] sum[j]
		//k:2*sum[i]
		auto j = st[t].idx;
		dp[i] = dp[j] + (sum[i] - sum[j]-m) * (sum[i] - sum[j]-m);
		point x(sum[i], dp[i]+sum[i]*sum[i]-2*m*sum[i], i);
		while (st.size() >= 2 && (st[st.size() - 1] - st[st.size() - 2]) / (x - st[st.size() - 1]) < 0) {
			st.pop_back();
		}
		st.push_back(x);
		if (t > st.size() - 1)t = st.size() - 1;
	}
	cout<<dp[n];
	return 0;
}
2024/11/10 16:37
加载中...