链接:https://ac.nowcoder.com/acm/contest/881/C
来源:牛客网
Bobo has a point A in the n dimension real space Rn, whose coodinate is (a1/m,a2/m,…,an/m) where ai and m are both integers. He wants to find another point P=(p1,p2,…,pn) meeting the following requirements.
- p1,p2,…,pn∈R. That is, they are real numbers.
- p1,p2,…,pn≥0
- p1+p2+⋯+pn=1
- The (squared) Euclidean distance between P and A, which is ∥A−P∥2=∑ni=∑(ai/m−pi)2, is minimized.
It can be proved the minimum is always a rational number. Print the squared distance in fraction. Note to print an integer n asn
instead ofn/1
.
输入描述:
The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains two integers n and m.
The second line contains n integers a1,a2,…,an.
- 1≤n≤104
- 1≤m≤103
- −m≤ai≤m
- The sum of n does not exceed 5×105.
输出描述:
For each test case, print a fraction which denotes the result.
输入
1 1
0
2 3
1 2
3 10
1 -2 3
输出
1
0
16/75
题意:
给定n个数字a1到an,要求n个实数p1到pn,使得∑(ai/m−pi)2最小
并且满足:
p1,p2,…,pn≥0
p1+p2+⋯+pn=1
输出最小的答案,用最简分数表示。
题解:
由于ai互相之间不会影响,所以顺序可以打乱。
将ai从大到小排序,枚举将最大的i个ai处理成同一个值,我们把前i个ai处理成同一个值的时候,假设代价为每个数字和它的初始值的绝对值之差,消耗的代价总和不能超过m。当不能继续放置的时候(设总代价为k),我们就可以将剩余的m−k的代价均摊到所有非负的ai值上,然后他们对答案分子的贡献就是(m−k−st∗v)2(st为处理成同一个值的ai个数,v那st个ai处理成的同一个值),剩余的每个ai对答案分子的贡献就是st∗a[i]∗a[i],分母的值为st∗m∗m
#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
using namespace std;
ll a[10004];
ll ans,m;
int n;
int w33ha(){
ans=0;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
sort(a+1,a+n+1,greater<int>());
ll nd=0;
for(int i=1;i<=n;i++){
if(i<n&&(a[i]-a[i+1])*i+nd<=m){
nd+=(a[i]-a[i+1])*i;
}
else{
ans=(m-nd-i*a[i])*(m-nd-i*a[i]);
for(int j=i+1;j<=n;j++){
ans+=i*a[j]*a[j];
}
ll d,p=i*m*m;
if(ans==0)return puts("0");
d=__gcd(ans,p);
ans/=d;p/=d;
if(p==1)printf("%lld\n",ans);
else printf("%lld/%lld\n",ans,p);
return 0;
}
}
return 0;
}
int main(){
while(scanf("%d%lld",&n,&m)!=EOF)w33ha();
return 0;
}