社区讨论

求助写法

P3810【模板】三维偏序 / 陌上花开参与者 5已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@lvggv7rh
此快照首次捕获于
2024/04/26 17:24
2 年前
此快照最后确认于
2024/04/26 18:09
2 年前
查看原帖
求问以下两种写法为何第一种能过第二种不行,两种都可过样例。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;

int n, k, ans[M];

namespace BIT {
	int B[M];
	void add(int x, int y) {
		for(; x <= k; x += (x & -x)) B[x] += y;
	}
	int ask(int x) {
		int sum = 0;
		for(; x > 0; x -= (x & -x)) sum += B[x];
		return sum;
	}
}
using namespace BIT;

struct node {
	int a, b, c, cnt, res;
	bool operator != (node rhs) {
		return (a != rhs.a || b != rhs.b || c != rhs.c);
	}
} c[N], lsh[N];

void cdq(int l, int r) {
	if(l == r) return;
	int mid = ((l + r) >> 1);
	cdq(l, mid); cdq(mid + 1, r);
	sort(lsh + l, lsh + mid + 1, [](node x, node y) {
		if(x.b != y.b) return x.b < y.b;
		else return x.c < y.c;
	});
	sort(lsh + mid + 1, lsh + r + 1, [](node x, node y) {
		if(x.b != y.b) return x.b < y.b;
		else return x.c < y.c;
	});
	int i = l, j = mid + 1; 
	for(; j <= r; j++) {
		for(; i <= mid && lsh[i].b <= lsh[j].b; i++) add(lsh[i].c, lsh[i].cnt);
		lsh[j].res += ask(lsh[j].c);
	}
	for(int t = l; t < i; t++) add(lsh[t].c, -lsh[t].cnt);
}

int main() {
	cin >> n >> k;
	for(int i = 1; i <= n; i++) {
		cin >> c[i].a >> c[i].b >> c[i].c;
	}
	sort(c + 1, c + n + 1, [](node x, node y) {
		if(x.a != y.a) return x.a < y.a;
		else if(x.b != y.b) return x.b < y.b;
		else return x.c < y.c;
	});
	int tot = 0, cnt = 0;
	for(int i = 1; i <= n; i++) {
		cnt++;
		if(c[i] != c[i + 1]) {
			lsh[++tot] = {c[i].a, c[i].b, c[i].c, cnt, 0};
			cnt = 0;
		}
	}
	cdq(1, tot);
	for(int i = 1; i <= tot; i++) ans[lsh[i].res + lsh[i].cnt - 1] += lsh[i].cnt;
	for(int i = 0; i < n; i++) cout << ans[i] << '\n';
	return 0;
}
接下来是第二种
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;

int n, k, ans[M];

namespace BIT {
	int B[M];
	void add(int x, int y) {
		for(; x <= k; x += (x & -x)) B[x] += y;
	}
	int ask(int x) {
		int sum = 0;
		for(; x > 0; x -= (x & -x)) sum += B[x];
		return sum;
	}
}
using namespace BIT;

struct node {
	int a, b, c, cnt, res;
	bool operator == (node rhs) {
		return (a == rhs.a && b == rhs.b && c == rhs.c);
	}
	bool operator < (node rhs) {
		if(a != rhs.a) return a < rhs.a;
		else if(b != rhs.b) return b < rhs.b;
		else return c < rhs.c;
	}
} c[N];

void cdq(int l, int r) {
	if(l == r) return;
	int mid = ((l + r) >> 1);
	cdq(l, mid); cdq(mid + 1, r);
	sort(c + l, c + mid + 1, [](node x, node y) {
		if(x.b != y.b) return x.b < y.b;
		else return x.c < y.c;
	});
	sort(c + mid + 1, c + r + 1, [](node x, node y) {
		if(x.b != y.b) return x.b < y.b;
		else return x.c < y.c;
	});
	int i = l, j = mid + 1; 
	for(; j <= r; j++) {
		for(; i <= mid && c[i].b <= c[j].b; i++) add(c[i].c, c[i].cnt);
		c[j].res += ask(c[j].c);
	}
	for(int t = l; t < i; t++) add(c[t].c, -c[t].cnt);
}

int main() {
	cin >> n >> k;
	for(int i = 1; i <= n; i++) {
		cin >> c[i].a >> c[i].b >> c[i].c;
		c[i].cnt = 1; c[i].res = 0;
	}
	sort(c + 1, c + n + 1);
	int tot = unique(c + 1, c + n + 1) - c - 1;
	sort(c + tot + 1, c + n + 1);
	for(int l = 1, r = tot + 1; r <= n && l <= tot; r++) {
		while(l <= tot && c[l] < c[r]) l++;
		c[l].cnt++;
	}
	cdq(1, tot);
	for(int i = 1; i <= tot; i++) ans[c[i].res + c[i].cnt - 1] += c[i].cnt;
	for(int i = 0; i < n; i++) cout << ans[i] << '\n';
	return 0;
}

回复

8 条回复,欢迎继续交流。

正在加载回复...