感觉在线不太好写,所以往离线方面想了。
离线的话需要维护双指针(当前的 $x$ 和 $y$,表示现在的答案是 $\sum\limits_{i=1}^{x} \sum\limits_{j=1}^{y} \left| A_i - B_j \right|$)并支持移动这两个指针,所以容易想到莫队。
之后需要支持统计答案,显然需要数据结构维护拆掉绝对值之后的东西,赛时有想过树状数组但是没写出来,还是我太菜了。
首先将 $a,b$ 离散化,然后以 $a$ 为例进行统计。
即分别计算 $b_j \gt a_i$ 和 $b_j \lt a_i$ 的数字总和、数量,就可以直接计算出绝对值。
$b$ 同理,于是套个莫队就做完了。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 15, Q = 1e4 + 15;
int n, q, B;
int m, a[N], b[N], c[N];
struct Queries {
int x, y, id;
} qry[Q];
inline bool cmp(Queries a, Queries b) {
if (a.x / B != b.x / B) return a.x < b.x;
return a.y < b.y;
}
struct BIT {
long long tr[N];
inline void add(int x, int d) { for ( ; x <= m; x += x & -x) tr[x] += d; }
inline long long query(int x) {
long long res = 0;
for ( ; x ; x -= x & -x) res += tr[x];
return res;
}
} sum[2], cnt[2];
//0 x - 1 y
long long ans[Q], Ans = 0;
inline void change(int val, bool xy, int opt) {
long long res = 0;
val = (xy == 0) ? a[val] : b[val];
//right
res += (sum[xy ^ 1].query(m) - sum[xy ^ 1].query(val)) - (cnt[xy ^ 1].query(m) - cnt[xy ^ 1].query(val)) * 1ll * c[val];
//left
res += (cnt[xy ^ 1].query(val) * 1ll * c[val]) - sum[xy ^ 1].query(val);
Ans += res * opt;
sum[xy].add(val, c[val] * opt), cnt[xy].add(val, opt);
}
inline void add(int x, bool opt) { change(x, opt, 1); }
inline void del(int x, bool opt) { change(x, opt, -1); }
int main() {
scanf("%d", &n), B = sqrt(n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), c[++m] = a[i];
for (int i = 1; i <= n; i++) scanf("%d", &b[i]), c[++m] = b[i];
sort(c + 1, c + 1 + m);
m = unique(c + 1, c + 1 + m) - c - 1;
for (int i = 1; i <= n; i++) a[i] = lower_bound(c + 1, c + 1 + m, a[i]) - c;
for (int i = 1; i <= n; i++) b[i] = lower_bound(c + 1, c + 1 + m, b[i]) - c;
scanf("%d", &q);
for (int i = 1; i <= q; i++) scanf("%d%d", &qry[i].x, &qry[i].y), qry[i].id = i;
sort(qry + 1, qry + 1 + q, cmp);
int x = 0, y = 0;
for (int i = 1; i <= q; i++) {
int xx = qry[i].x, yy = qry[i].y;
while (x < xx) add(++x, 0);
while (y < yy) add(++y, 1);
while (x > xx) del(x--, 0);
while (y > yy) del(y--, 1);
ans[qry[i].id] = Ans;
}
for (int i = 1; i <= q; i++) printf("%lld\n", ans[i]);
return 0;
}