题目链接
题解:
考虑将一个胡萝卜分成K段,那么这个胡萝卜肯定是尽可能的均分才能贡献最小
因为一个胡萝卜切的次数越多,x / cnt下降的越少,因此胡萝卜切的次数越多,它的平方和减少的越少
那么可以用优先队列维护平方和下降的值,每次减去贡献平方和减少最多的胡萝卜即可
代码:
/*
* @Author : Nightmare
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define PII pair<int,int>
#define ls 2 * rt
#define rs 2 * rt + 1
#define gcd(a,b) __gcd(a,b)
#define eps 1e-6
#define lowbit(x) (x&(-x))
#define N 100005
#define M 100005
#define mod 1000000007
#define inf 0x3f3f3f3f
struct node{
int a, b, c;
friend bool operator < (node x, node y){ return x.a < y.a; }
};
priority_queue<node> que;
int cut(int a, int x){
int m = a / x, t = a % x;
return t * (m + 1) * (m + 1) + (x - t) * m * m;
}
void solve(){
int n, k, ans = 0; cin >> n >> k;
for(int i = 1, x; i <= n ; i ++) cin >> x, ans += x * x, que.push({cut(x, 1) - cut(x, 2), x, 2});
for(int i = n ; i < k ; i ++){
int a = que.top().a, b = que.top().b, c = que.top().c; que.pop();
ans -= a;
que.push({cut(b, c) - cut(b, c + 1), b, c + 1});
}
cout << ans << '\n';
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("D:\\in.txt", "r", stdin);
#endif
solve();
#ifndef ONLINE_JUDGE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}