题解:P15546 「Stoi2037」七里香
dingziyang888 · · 题解
五年级 xxs 赛时被卡溢出了呜呜呜。
本文同步发表于博客园。
推式子
这个推式子推了我半小时,感觉推复杂了,不过也在赛后补题的时候过了。
什么文字的太多了,直接看形式化题意,让我们求
的最大值。
我们定义第
则原式变为
我们令原式为
而
则
方便计算,记
则
下面分别计算
化简 S
注意到
对于固定的
个区间,则
记
把
记
于是
化简 T
同上一部分,可交换求和顺序并化简
拆开
对于第一个
对于第二个
于是
记
则
排序不等式
排序不等式(知道了之后你甚至可以切蓝题)
其中
且
排序不等式证明
令
如果
知
也就说明
同理,可以得到
重复这个过程,经过最多
同理可知
当
当
于是
且
从而
故这两个等式中必有一个不成立。
所以当且仅当
最大化 T
已知
由排序不等式:要使
因此我们按
代码
::::success[code]
#include <bits/stdc++.h>
#define pub public:
#define pri private:
#define fri friend:
#define Ofile(s) freopen(s".in", "r", stdin), freopen (s".out", "w", stdout)
#define Cfile(s) fclose(stdin), fclose(stdout)
#define fast ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using lb = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
constexpr int mod = 998244353;
constexpr int maxn = 1e5 + 5;
constexpr int maxk = 1e6 + 5;
ll n, k, cur_val, r, out, total;
i128 S, T, tmp, ans;
ll sum[maxk], idx[maxn];
i128 w[maxn];
void print_unsigned(ui128 t){
if (t >= 10)
print_unsigned(t / 10);
putchar('0' + t % 10);
}
void print(i128 t){
if (t < 0){
putchar('-');
ui128 tmpp = -(ui128)t;
print_unsigned(tmpp);
}
else if (!t)
putchar('0');
else
print_unsigned((ui128) t);
}
int main() {
freopen("contest.in", "r", stdin);
freopen("contest.out", "w", stdout);
cin >> n >> k;
for (int i = 1, x; i <= n; i++)
cin >> x, sum[x]++;
for (ll d = 1; d <= n - 1; d++){
tmp = (i128)d * (n - d) * (n - d + 1) * (n - d + 2) / 6;
S += tmp;
}
S *= k;
for (ll i = 1; i <= n; i++)
w[i] = (i128)i * (n - i + 1) * (2 * i - n - 1) / 2;
for (int i = 1; i <= n; i++)
idx[i] = i;
sort(idx + 1, idx + n + 1, [&](int x, int y) {
return w[x] > w[y];
});
cur_val = k;
while (cur_val >= 1 && sum[cur_val] == 0)
cur_val--;
r = sum[cur_val];
for (ll i = 1; i <= n; i++){
if (total >= n) break;
ll pos = idx[i];
T += w[pos] * cur_val;
total++;
r--;
while (!r && cur_val > 1)
cur_val--, r = sum[cur_val];
}
ans = S + T;
print(ans);
return 0;
}
::::