题目链接
根据题意,d是两个点的最短距离,分析知,假设(x_i)<(x_j), 若(v_i)>(v_j),那么d(i,j)一定为0,因为i一定能追上j,否则,d(i,j)就为其初始距离
那我们就转化问题为一个二维偏序问题,求(x_i)<(x_j)且(v_i)<(v_j),满足这个条件的每个点对之间的距离
很容易想到定一序,另一序用树状数组维护的统计法,假设现在是(x_i),满足上述条件有k个,那么,对(x_i)的统计答案为:(sum_{j=i-k}^{i-1}(x_i-x_j)),拆开,就是(k*x_i-sum_{j=i-k}^{i-1}x_j)
那我们可以维护2个树状数组,分别维护上述的2个数,满足条件的个数与满足条件的这些数的x的和即可
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;
const int maxn = 2e5+5;
struct Node {
int x, v;
} Nodes[maxn];
int all_x[maxn];
LL C1[maxn], C2[maxn];
void add(LL val, int pos, int n) {
for(; pos <= n; pos += lowbit(pos))
C1[pos] += val, C2[pos]++;
}
pair<LL,LL> getsum(int pos) {
LL ret1 = 0, ret2 = 0;
for(;pos;pos-=lowbit(pos))
ret1 += C1[pos], ret2 += C2[pos];
return make_pair(ret1,ret2);
}
void run_case() {
int n;
cin >> n;
for(int i = 1; i <= n; ++i) {
cin >> Nodes[i].x;
all_x[i] = Nodes[i].x;
}
for(int i = 1; i <= n; ++i) {
cin >> Nodes[i].v;
}
sort(all_x+1, all_x+1+n);
int len = unique(all_x+1, all_x+1+n) - all_x - 1;
for(int i = 1; i <= n; ++i) {
Nodes[i].x = lower_bound(all_x+1, all_x+1+len, Nodes[i].x) - all_x;
}
sort(Nodes+1, Nodes+1+n, [&](Node &a, Node&b) {
return a.v < b.v || (a.v == b.v && a.x < b.x);
});
LL ans = 0;
for(int i = 1; i <= n; ++i) {
add(all_x[Nodes[i].x], Nodes[i].x, n);
auto now = getsum(Nodes[i].x-1);
ans += 1LL*now.second*all_x[Nodes[i].x] - now.first;
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(10);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}