POJ1990-MooFest

来源:互联网 发布:国外社交网站 知乎 编辑:程序博客网 时间:2024/05/21 21:43

这道题靠暴力朴素的n^2算法显然是过不了的,因此我们要对算法进行优化,先将读入的每个牛的信息按音量进行排序,这样每头牛只需将比它小的牛的距离总和加起来乘以牛的音量即可。借助两个树状数组,一个维护牛的数量,另一个维护牛的坐标和,这样每次计算出一头牛的左右两边的牛的距离总和并与牛的音量相乘再将牛加入树状数组,反复即可。

#include <cstdio>#include <algorithm>using namespace std;const int maxn = 20000;typedef pair<int, int> P;P v[maxn];long long bit1[maxn+2];long long bit2[maxn+2];int n;int lowbit(int x) {    return x & -x;}void add(long long *bit, int i, int delta) {    for (int j = i; j <= maxn; j += lowbit(j)) {        bit[j] += delta;    }}long long sum(long long *bit, int k) {    long long ans = 0;    for (int i = k; i > 0; i -= lowbit(i)) {        ans += bit[i];    }    return ans;}int main(int argc, char const *argv[]) {    scanf("%d", &n);    for (int i = 0; i < n; i++) {        scanf("%d%d", &v[i].first, &v[i].second);    }    sort(v, v + n);    long long ans = 0;    for (int i = 0; i < n; i++) {        long long left = sum(bit1, v[i].second) * v[i].second - sum(bit2, v[i].second);        long long right = sum(bit2, maxn) - sum(bit2, v[i].second) - (i - sum(bit1, v[i].second)) * v[i].second;        ans += (left + right) * v[i].first;        add(bit1, v[i].second, 1);        add(bit2, v[i].second, v[i].second);    }    printf("%lld\n", ans);    return 0;}
0 0
原创粉丝点击