注意到已经有两维偏序。
接着数对 $(i,j)$ 有贡献仅当满足以下两组条件之一:
- $i \gt j, T_i \lt T_j, a_i \lt a_j$
- $i \lt j, T_i \lt T_j, a_i \gt a_j$
发现两组条件都有 $T_i \lt T_j$,所以考虑最外层对 $T$ 升序排序。
至于另外两维,就是三维偏序了,分别做一遍 CDQ 即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 15;
int n, m;
int p[N], pos[N];
struct node {
int tm, id, a;
} a[N], b[N];
bool cmp(node a, node b) {
return a.tm < b.tm;
}
int tr[N];
void add(int x, int d) {
for ( ; x < N; x += x & -x) tr[x] += d;
}
int query(int x) {
int res = 0;
for ( ; x ; x -= x & -x) res += tr[x];
return res;
}
long long res = 0;
long long sum[N], ans[N];
void init() {
for (int i = 1; i <= n; i++) {
sum[i] += (i - 1) - query(p[i]);
add(p[i], 1);
}
for (int i = 1; i <= n; i++) res += sum[i];
for (int i = 0; i <= n; i++) tr[i] = 0;
for (int i = n; i >= 1; i--) {
sum[i] += query(p[i]);
add(p[i], 1);
}
for (int i = 0; i <= n; i++) tr[i] = 0;
}
void cdq1(int l, int r) {
if (l >= r) return;
int mid = l + r >> 1;
cdq1(l, mid), cdq1(mid + 1, r);
for (int i = l, j = mid + 1, k = l; k <= r; k++) {
if ((j > r) || (i <= mid && a[i].id > a[j].id)) add(a[i].a, 1), b[k] = a[i++];
else {
ans[a[j].tm] += query(a[j].a);
b[k] = a[j++];
}
}
for (int i = l; i <= mid; i++) add(a[i].a, -1);
for (int i = l; i <= r; i++) a[i] = b[i];
}
void cdq2(int l, int r) {
if (l >= r) return;
int mid = l + r >> 1;
cdq2(l, mid), cdq2(mid + 1, r);
for (int i = l, j = mid + 1, k = l; k <= r; k++) {
if ((j > r) || (i <= mid && a[i].a > a[j].a)) add(a[i].id, 1), b[k] = a[i++];
else {
ans[a[j].tm] += query(a[j].id);
b[k] = a[j++];
}
}
for (int i = l; i <= mid; i++) add(a[i].id, -1);
for (int i = l; i <= r; i++) a[i] = b[i];
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", &p[i]), pos[p[i]] = i;
for (int i = 1, x; i <= m; i++) scanf("%d", &x), a[i] = (node){i, pos[x], x};
init();
sort(a + 1, a + 1 + m, cmp);
cdq1(1, m);
sort(a + 1, a + 1 + m, cmp);
cdq2(1, m);
sort(a + 1, a + 1 + m, cmp);
for (int i = 1; i <= m; i++) {
printf("%lld\n", res);
res += ans[i] - sum[pos[a[i].a]];
}
return 0;
}
分块秒了,只能说不支持在线,强制就废了(雾
那有没有在线的做法?
有呀,如果我没有记错树套树和分块都可以,建议分块,树套树得卡卡常。
ok,佬的洛谷号是多少?
https://www.luogu.com.cn/problem/P1975
我只做了这道题,也可以套CDQ的板,比那个CQ的难想。
你可以看一看,反正我是用的分块
(大分块统治世界)https://www.luogu.com.cn/user/556908
哥们也给个谷呗。