codeforces1428E Carrots for Rabbits

it2025-04-12  21

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

一打开榜发现E比D过得还多,就果断先写E

可以发现一个胡萝卜如果要分为num[i]段,那么肯定是平均更好,就可以轻松算出来a[i]分成Num[i]段的最小的平方和

然后我们就贪心地去选择选择哪一个胡萝卜从分成num[i]段变成num[i]+1段,他能减少的代价最大就行了

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxl=3e5+10; int n,m,k,cnt,tot,cas;ll ans; ll a[maxl]; int num[maxl]; bool vis[maxl]; char s[maxl]; typedef pair <ll,int> p; priority_queue<p> q; inline ll calc(ll x,int i) { ll d,res; d=x/i;res=x%i; return d*d*(i-res)+(d+1)*(d+1)*res; } inline void prework() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); ans=0; for(int i=1;i<=n;i++) { ans+=a[i]*a[i];num[i]=1; if(a[i]==1) q.push({0ll,i}); else q.push({calc(a[i],1)-calc(a[i],2),i}); } } inline void mainwork() { p d;int id; for(int i=n+1;i<=k;i++) { d=q.top();q.pop(); ans-=d.first;id=d.second; num[id]++; if(a[id]<=num[id]) q.push({0ll,id}); else q.push({calc(a[id],num[id])-calc(a[id],num[id]+1),id}); } } inline void print() { printf("%lld\n",ans); } int main() { int t=1; //scanf("%d",&t); for(cas=1;cas<=t;cas++) { prework(); mainwork(); print(); } return 0; }

 

最新回复(0)