題目連結
求\(\displaystyle \sum_{i=1}^N \sum_{j=i+1}^N \max(A_j - A_i, 0)\)
Hint: 可以透過兩個樹狀陣列,第一個維護\(\leq c_i\)的數值和,第二個維護\(\leq c_i\)的個數,需要離散化
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
//#define int long long
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int base = 131;
const int inf = INT_MAX;
const int mod = 1e9 + 7;
const int N = 4e5 + 5;
int n;
vector<int> a(N), cnt(N);
vector<ll> sum(N);
int lowbit(int x) {return x & -x;}
void upd(int x, int d) {
while (x <= n) {
sum[x] += d;
x += lowbit(x);
}
}
ll query(int x) {
ll ans = 0;
while (x) {
ans += sum[x];
x -= lowbit(x);
}
return ans;
}
void upd1(int x, int d) {
while (x <= n) {
cnt[x] += d;
x += lowbit(x);
}
}
int query1(int x) {
int ans = 0;
while (x) {
ans += cnt[x];
x -= lowbit(x);
}
return ans;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
vector<int> v = a;
vector<int> c(n + 1);
sort(v.begin() + 1, v.begin() + 1 + n);
int len = unique(v.begin() + 1, v.begin() + 1 + n) - v.begin() - 1;
for (int i = 1; i <= n; i++) {
c[i] = lower_bound(v.begin() + 1, v.begin() + 1 + len, a[i]) - v.begin();
//cout << c[i] << " \n"[i == n];
}
ll ans = 0;
for (int i = 1; i <= n; i++) {
upd(c[i], a[i]);
upd1(c[i], 1);
ans += 1LL * query1(c[i]) * a[i] - query(c[i]);
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1;
//cin >> T;
while (T--) {
solve();
}
return 0;
}