设 \(F(n,m)\) 是将 \(n\) 个同种族的人放到 \(m\) 个队伍中可以获得的贡献。可以发现在同一个队伍中的人不能互相产生贡献,所以尽可能平均分配是最优的。
设 \(p=\lfloor \dfrac{n}{m}\rfloor,q=n\bmod m\),那么有 \(m-q\) 个队伍中有 \(p\) 个人,\(q\) 个队伍中有 \(p+1\) 个人,贡献是
\[F(n,m)=\dfrac{n(n+1)}{2}-(m-q)\times\dfrac{p(p+1)}{2}-q\times\dfrac{(p+1)(p+2)}{2} \]设 \(f_j\) 是分成 \(j\) 个队伍可以获得的贡献,枚举每个种族 \(i\),使 \(f_j\gets f_j+F(c_i,min(j,c_i))\),相当于单点加与后缀加,差分前缀和就行了。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=2e5+10;
int T,n,b,z,c[MAXN],f[MAXN],MAX,ans;
inline int F(int x,int y)
{
int p=x/y,q=x%y;
return x*(x+1)/2-(y-q)*p*(p+1)/2-q*(p+1)*(p+2)/2;
}
inline void work()
{
cin>>n>>b>>z;
for(int i=1;i<=n;++i)
{
cin>>c[i];MAX=max(MAX,c[i]);
for(int j=1;j<c[i];++j)
{
int cur=F(c[i],j)*b;
f[j]+=cur,f[j+1]-=cur;
}
f[c[i]]+=F(c[i],c[i])*b;
}
for(int i=1;i<=MAX;++i)
f[i]+=f[i-1],ans=max(ans,f[i]-(i-1)*z);
for(int i=1;i<=MAX;++i) f[i]=0;
cout<<ans<<'\n';MAX=ans=0;return ;
}
signed main()
{
cin.tie(0),cout.tie(0);
ios::sync_with_stdio(0);
cin>>T;while(T--) work();
return 0;
}
标签:Mountain,Lonely,int,dfrac,队伍,MAXN,CF1928D,MAX,include
From: https://www.cnblogs.com/int-R/p/18013982/CF1928D