UVA11990 ``Dynamic'' Inversion
UVA11990 ``Dynamic'' Inversion
对于每一个被删的三元组 (分别表示第 个数的位置,删除时间及权值),消失的逆序对 为:
- 满足 的 。
- 满足 的 。
明显的三维偏序问题,做一次 CDQ
即可。
时间复杂度 。
#include <bits/stdc++.h>
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
const int _ = 5e5 + 10;
int n, m, tot, r[_], c[_];
struct node {
int x, y, z, ans; // x:位置 y: 时间 z: 权值
} a[_], b[_];
inline bool cmp(node u, node v) {
if (u.x == v.x) {
if (u.y == v.y) return u.z < v.z;
return u.y < v.y;
}
return u.x < v.x;
}
inline void update(int x, int val) {
for (int i = x; i <= 4e5 + 10; i += i & -i) c[i] += val;
}
inline int query(int x) {
int res = 0;
for (int i = x; i; i -= i & -i) res += c[i];
return res;
}
void cdq(int l, int r) {
if (l == r) return;
int mid = (l + r) >> 1;
cdq(l, mid), cdq(mid + 1, r);
int ql = l, qr = mid + 1, k = l;
while (ql <= mid && qr <= r) {
if (a[ql].y > a[qr].y) {
update(a[ql].z, 1);
b[k++] = a[ql++];
} else {
a[qr].ans += query(4e5 + 9) - query(a[qr].z);
b[k++] = a[qr++];
}
}
while (ql <= mid) {
update(a[ql].z, 1);
b[k++] = a[ql++];
}
while (qr <= r) {
a[qr].ans += query(4e5 + 9) - query(a[qr].z);
b[k++] = a[qr++];
}
for (int i = l; i <= mid; ++i) update(a[i].z, -1);
ql = l, qr = mid + 1, k = l;
while (ql <= mid && qr <= r) {
if (a[ql].y < a[qr].y) {
update(a[qr].z, 1);
b[k++] = a[qr++];
} else {
a[ql].ans += query(a[ql].z);
b[k++] = a[ql++];
}
}
while (qr <= r) {
update(a[qr].z, 1);
b[k++] = a[qr++];
}
while (ql <= mid) {
a[ql].ans += query(a[ql].z);
b[k++] = a[ql++];
}
for (int i = mid + 1; i <= r; ++i) update(a[i].z, -1);
for (int i = l; i <= r; ++i) a[i] = b[i];
}
bool cmp2(node u, node v) {
return u.y < v.y;
}
signed main() {
while (~scanf("%d%d", &n, &m)) {
memset(c, 0, sizeof c);
memset(r, 0, sizeof r);
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
for (int i = 1; i <= n; ++i) {
a[i].x = i;
a[i].z = read();
r[a[i].z] = i;
}
for (int i = 1; i <= m; ++i)
a[r[read()]].y = i;
for (int i = 1; i <= n; ++i)
if (a[i].y == 0) a[i].y = m + 1;
long long res = 0;
for (int i = 1; i <= n; ++i) {
res += query(n + 1) - query(a[i].z);
update(a[i].z, 1);
}
for (int i = 1; i <= n; ++i)
update(a[i].z, -1);
sort(a + 1, a + n + 1, cmp);
cdq(1, n);
sort(a + 1, a + n + 1, cmp2);
for (int i = 1; i <= m; ++i) {
printf("%lld\n", res);
res -= a[i].ans;
}
}
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122011