CF 1428E Carrots for Rabbits

https://codeforces.ml/contest/1428/problem/E

优先队列题,需要维护的东西是将一个萝卜拆成t份的获得值:

假设当前它被均分为t - 1份,则拆分为t份只需要多一次操作,也即上帝视角可以反悔。

这个获得值就是拆成t份与拆成t - 1份之后的二者平方和的差。

参考:https://blog.csdn.net/I_have_a_world/article/details/109151018

 1 #include<bits/stdc++.h> 
 2 #define ll long long
 3 using namespace std;
 4 
 5 const ll N = 1e5 + 10;
 6 
 7 struct node{
 8     ll val, b, c;//val是多切一份的获得值,b是算作一份的总和,c是下一步即将分成的份数 
 9     bool operator < (const node &i)const{
10         return val < i.val;
11     }
12 };
13 priority_queue<node> q;
14 
15 ll gv(ll a, ll x)
16 {//将a切成x份的结果 
17     ll m = a / x, t = a % x;
18     return t * (m + 1) * (m + 1) + (x - t) * m * m;
19 }
20 
21 int main(){
22     ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
23     ll n, k; cin >> n >> k;
24     ll ans = 0;
25     for(int i = 1 ; i <= n ; i++){
26         ll x; cin >> x;
27         q.push({gv(x, 1) - gv(x, 2), x, 2});
28         ans += x * x;
29     }
30     for(int i = 1 ; i <= k - n ; i++){
31         node now = q.top();
32         q.pop();
33         ll val = now.val, b = now.b, c = now.c;
34         ans -= val;
35         q.push({gv(b, c) - gv(b, c + 1), b, c + 1});
36     }
37     cout << ans << endl;
38     
39     return 0;
40 }
原文地址:https://www.cnblogs.com/ecustlegendn324/p/14266483.html