题目大意
N头牛排成一排,现在给出它们的坐标x[i]和听觉阈值v[i]. 两头牛i和j之间谈话的音量为max(v[i], v[j]) * dist(i, j)
dist表示两者距离。求所有N*(N-1)对牛谈话音量的总和。
题目分析
按v[i]降序排序。然后用BIT求出每一头牛和后面的牛的距离的和即可。(我用了两个BIT,一个维护累计和,一个维护个数)
source code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <cstdio> #include <algorithm> using namespace std; const int maxn = 20200; typedef long long ll; int n = 20000;
int lowbit(int x) { return x & -x; }
ll bit[maxn];
ll sum(int i) { ll res = 0; for (; i; i -= lowbit(i)) { res += bit[i]; } return res; }
void add(int i, ll x) { for (; i <= n; i += lowbit(i)) { bit[i] += x; } }
ll bit2[maxn];
ll sum2(int i) { ll res = 0; for (; i; i -= lowbit(i)) { res += bit2[i]; } return res; }
void add2(int i, ll x) { for (; i <= n; i += lowbit(i)) { bit2[i] += x; } }
struct cow { int v, x; bool operator < (const cow & b) const { return v > b.v; } }a[maxn];
int main() { int N; scanf("%d", &N); for (int i = 0; i < N; i++) scanf("%d%d", &a[i].v, &a[i].x), add(a[i].x, a[i].x), add2(a[i].x, 1); sort(a, a + N); ll ans = 0; for (int i = 0; i < N - 1; i++) { add(a[i].x, -a[i].x); add2(a[i].x, -1); ll dist_tot = sum2(a[i].x) * a[i].x - sum(a[i].x) + sum(n) - sum(a[i].x) - (sum2(n) - sum2(a[i].x)) * a[i].x; ans += dist_tot * a[i].v; } printf("%lld\n", ans); }
|
Last updated: