题意很简单就是求这个
的最小值。
但不过有一些约束条件
首先当时第一眼,直接均值不等式
然后一会儿样例过了,然后WA了。
然后讲题解就看见一个拉格朗日乘子法。我虽然依稀会一点,但不过没有做过还有不等式约束的式子啊。。。。
然后看了一下拉格朗日乘子法和KTT没一个看懂,全是专业的数学用语,然后直接例题都看不懂,还写了几个小时。哎太菜了。
后来看了看那些大佬的代码,发现都差不多。
最后还是我队友想了一种方法,就是理解上面的式子的图像意义。
就是到ai/m这些点的距离的平方的最小值。然后对于为负数的点,相对应的pi取为零。
对为正数的ai/m用均值不等式。可以样例都过不了。
然后思考了很久,发现即使小于零也可以使用均值不等式。
如何判断呢。
首先,因为pi为大于零的数,ai为大于等于-m,小于等于m的数。
假设前i个能取等号。在加上第i+1个能取等号。
则必有这样的判断式
假设如果右边大于的时候也成立。
则有这样的式子
处理一下可以得到
可以得到pi+1时小于零的,与题意矛盾,故不满足
#include "bits/stdc++.h"
using namespace std;
const double eps = 1e-8;
#define lowbit(x) x&-x
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fi first
#define se second
#define make_pair makp
int dcmp(double x) {
if (fabs(x) < eps) return 0;
return (x > 0) ? 1 : -1;
}
typedef long long ll;
typedef unsigned long long ull;
const ull hash1 = 201326611;
const ull hash2 = 50331653;
const int N = 100000 + 10;
const int M = 2048 + 10;
const int inf = 0x3f3f3f3f;
const ll mod = 998244353;
ll n, m, a[N], sum[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0), cerr.tie(0);
while (cin >> n >> m) {
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1, greater<>{});
ll p, q, cnt = n;
sum[0] = 0;
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + a[i];
}
for (int i = 1; i < n; i++) {
if (a[i + 1] * i < sum[i] - m) {
cnt = i;
break;
}
}
q = cnt;
p = (sum[cnt] - m) * (sum[cnt] - m);
for (int i = cnt + 1; i <= n; i++) {
p += a[i] * a[i] * q;
}
q *= m * m;
ll d = __gcd(p, q);
p /= d, q /= d;
if (p == 0) cout << "0" << endl;
else if (q == 1) cout << p << endl;
else cout << p << "/" << q << endl;
}
return 0;
}