AtCoder Beginner Contest 351 F题 Double Sum

F题:Double Sum

标签:扫描线、树状数组、线段树
题意:给定序列 A A A,计算 ∑ i = 1 N ∑ j = i + 1 N max ⁡ ( A j − A i , 0 ) \displaystyle \sum_{i=1}^N \sum_{j=i+1}^N \max(A_j - A_i, 0) i=1Nj=i+1Nmax(AjAi,0)
题解:观察公式,我们按照顺序遍历序列 A A A中的数,固定 A j A_j Aj,就变成了求当前数字和前面所有比自己小的数字之差的和。即公式: ∑ i = 1 j − 1 A j − A i \displaystyle \sum_{i=1}^{j-1} A_j - A_i i=1j1AjAi在满足条件 A j > A i A_j\gt A_i Aj>Ai的情况下。
我们将这个式子展开: A j ∑ i = 1 j − 1 − ∑ i = 1 j − 1 A i A_j\displaystyle \sum_{i=1}^{j-1} - \displaystyle \sum_{i=1}^{j-1}A_i Aji=1j1i=1j1Ai在满足条件 A j > A i A_j\gt A_i Aj>Ai的情况下。
通俗点讲,假设对于 A j A_j Aj来说,在它前面有 m m m个比它小的数 A i A_i Ai,那么值就是 m m m A j A_j Aj之和减去所有在第 j j j个数之前比它小的 A i A_i Ai之和。这个东西可以通过树状数组或者线段树进行维护。这题数据量比较大,需要离散化处理下。
代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll N = 4e5 + 10;
ll n, b[N], num[N], sum[N], ans = 0;
struct node {
    ll a, id;
}p[N];

bool cmp1(node x, node y) {
    if (x.a == y.a) return x.id < y.id;
    return x.a < y.a;
}

bool cmp2(node x, node y) {
    return x.id < y.id;
}


ll lowbit(ll x) {
    return x & (-x);
}

void update(ll *tree, ll x, ll k) {
    for (ll i = x; i <= n; i += lowbit(i)) tree[i] += k;
}

ll query(ll *tree, ll x) {
    ll res = 0;
    for (ll i = x; i > 0; i -= lowbit(i)) res += tree[i];
    return res;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> p[i].a;
        p[i].id = i;
    }
    sort(p + 1, p + 1 + n, cmp1);
    for (int i = 1; i <= n; i++) b[p[i].id] = i;
    sort(p + 1, p + 1 + n, cmp2);
    for (int i = 1; i <= n; i++) {
        ans += p[i].a * query(num, b[i] - 1);
        ans -= query(sum, b[i] - 1);
        update(num, b[i], 1);
        update(sum, b[i], p[i].a);
    }
    cout << ans;
    return 0;
}
  • 14
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值