Description
你有长度为n的成绩序列,最终成绩为去掉一个最低的成绩后剩下的平均值(多个最低只去掉一个),现在你可以删除前k个(1<=k<=n-2),按升序输出所有可以使你最终成绩最高的K的值。
Solution
考虑线段树, 维护区间和与区间最小值,最后枚举k,计算出平均值,更新答案
Code
#include <bits/stdc++.h> const int N = 1e5 + 10; using namespace std; int n, summ, m, cnt; int a[N], ans[N]; struct emmm { int l, r; int sum, minn; #define l(x) tr[x].l #define r(x) tr[x].r #define sum(x) tr[x].sum #define minn(x) tr[x].minn } tr[N << 2]; void build(int p, int l, int r) { l(p) = l; r(p) = r; if (l == r) { sum(p) = a[l]; minn(p) = a[l]; return ; } int mid = (l + r) >> 1; build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r); sum(p) = sum(p << 1) + sum(p << 1 | 1); minn(p) = min(minn(p << 1), minn(p << 1 | 1)); } void query(int p, int l, int r) { if (l <= l(p) && r >= r(p)) { summ += sum(p); m = min(m, minn(p)); return ; } int mid = (l(p) + r(p)) >> 1; if (l <= mid) query(p << 1, l, r); if (r > mid) query(p << 1 | 1, l, r); return ; } int main() { ios::sync_with_stdio(0); cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; build(1, 1, n); double t = 0; for (int i = 1; i <= n - 2; i++) { summ = 0; m = 0x3f3f3f; query(1, i + 1, n); double s = (double)(summ - m) / (double)(n - i - 1); if (t == s) ans[++cnt] = i; else if (s > t) { cnt = 0; ans[++cnt] = i; t = s; } } for (int i = 1; i <= cnt; i++) cout << ans[i] << endl; return 0; }