UVA11990 ``Dynamic'' Inversion

UVA11990 ``Dynamic'' Inversion

对于每一个被删的三元组 (i,ti,ai)(i,t_i,a_i)(分别表示第 ii 个数的位置,删除时间及权值),消失的逆序对 (i,j)(i,j) 为:

  • 满足 j<i,aj>ai,tj>tij<i,a_j>a_i,t_j>t_ijj
  • 满足 j>i,aj<ai,tj>tij > i,a_j<a_i,t_j>t_ijj

明显的三维偏序问题,做一次 CDQ 即可。

时间复杂度 O(nlog2n)\mathcal O(n \log^2 n)

#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;
}
posted @ 2022-05-29 09:37  蒟蒻orz  阅读(1)  评论(0编辑  收藏  举报  来源