斜率优化,求调,10pts
查看原帖
斜率优化,求调,10pts
1036693
carp_oier楼主2023/7/14 17:47
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rl register ll

const ll N = 4e6+10, M = 510;

ll n, m, f[N], cnt[N], s[N], q[N];

inline ll get(ll j) {
	return f[j] + s[j];
}

int main() {
	std::ios::sync_with_stdio(false);

	cin >> n >> m;

	ll maxx=-1e12;

	for(rl i=1 ; i <= n; ++ i) {
		ll t;
		cin >> t;
		maxx = max(maxx, t);
		cnt[t]++;
		s[t] += t;
	}

	for(rl i=1; i < maxx + m; ++ i) {
		cnt[i] += cnt[i-1];
		s[i] += s[i-1];
	}

	ll hh = 1, tt = 1;
	q[1] = 0;
	
	for(rl i=1; i< m;++ i) f[i] = cnt[i] * i - s[i];
	
	for(rl i=m; i < maxx+m; ++ i) {
			if(hh < tt && (get(q[hh+1]) - get(q[hh])) <= i * (q[hh+1] - q[hh])) ++ hh;
			ll j = q[hh];
			f[i] = f[j] + i * (cnt[i] - cnt[j]) - (s[i] - s[j]);
			while(hh < tt && (get(q[tt]) - get(q[tt-1])) * (cnt[i-m+1] - cnt[q[tt]]) >= (get(i-m+1), get(q[tt])) * (cnt[q[tt]] - cnt[q[tt-1]])) -- tt;
			q[++tt] = i - m + 1;
	}

	ll ans = 1e12;
	for (rl i=maxx; i < maxx + m; ++i) ans = min(ans, f[i]);
	cout << ans;
	return 0;
}
2023/7/14 17:47
加载中...