1 条题解
-
0
自动搬运
来自洛谷,原作者为

hehezhou
**搬运于
2025-08-24 22:10:11,当前版本为作者最后更新于2019-05-21 13:03:03,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意
给定,
求 的最小值首先根据
小学数学知识,我们把它转化为:考虑实际意义,一条数轴上有个点,要求数轴上一点,使该点到各点的距离和最小
显然,当这个点为第个点时为一个最优解(即中位数)然后用平衡树维护中位数,并统计答案即可(当然你用两个堆也可以)
注意总个数可能爆
Talk is cheap, show me the code.
码风很丑,大佬轻喷
#include <bits/stdc++.h> using namespace std; // 以下平衡树(无旋treap) struct node { int rnd, cnt, ls, rs; long long size; double sum, key; } t[500010]; inline int newnode(double key, int cnt) { static int Cnt = 0; t[++Cnt] = node{rand(), cnt, 0, 0, (long long)cnt, key * cnt, key}; return Cnt; } inline void up(int x) { t[x].size = t[t[x].ls].size + t[t[x].rs].size + t[x].cnt; t[x].sum = t[t[x].ls].sum + t[t[x].rs].sum + t[x].key * t[x].cnt; } inline int merge(int a, int b) { if(a == 0 || b == 0) return a | b; if(t[a].rnd < t[b].rnd) return t[a].rs = merge(t[a].rs, b), up(a), a; return t[b].ls = merge(a, t[b].ls), up(b), b; } inline void split_key(int now, double k, int &x, int &y) { if(now == 0) x = y = 0; else if(t[now].key > k) y = now, split_key(t[now].ls, k, x, t[y].ls), up(y); else x = now, split_key(t[now].rs, k, t[x].rs, y), up(x); } inline void split_rank(int now, long long k, int &x, int &y) { if(now == 0) x = y = 0; else if(t[t[now].ls].size >= k) y = now, split_rank(t[now].ls, k, x, t[y].ls), up(y); else x = now, split_rank(t[now].rs, k - t[t[now].ls].size - t[now].cnt, t[x].rs, y), up(x); } inline double get_max(int now) { if(t[now].rs) return get_max(t[now].rs); return t[now].key; } //平衡树结束 int n, a[500010], b[500010], rt; double lala; int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", a + i); for(int i = 1; i <= n; i++) scanf("%d", b + i); for(int i = 1; i <= n; i++) { if(a[i] < 0) a[i] = -a[i], b[i] = -b[i]; //加绝对值 int x, y; if(a[i] == 0) lala += abs(b[i]); //特判 else { double add = -1.0 * b[i] / a[i]; split_key(rt, add, x, y); rt = merge(merge(x, newnode(add, a[i])), y); } double mid; split_rank(rt, (t[rt].size + 1) / 2, x, y); mid = get_max(x); printf("%.10lf\n", lala + mid * t[x].size - t[x].sum + t[y].sum - mid * t[y].size); rt = merge(x, y); } return 0;//完结撒花 }
- 1
信息
- ID
- 4367
- 时间
- 3000ms
- 内存
- 500MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者