QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#138986#6520. Classic ProblemSanguineChameleonWA 515ms17076kbC++204.8kb2023-08-12 15:31:012023-08-12 15:33:16

Judging History

你现在查看的是最新测评结果

  • [2023-08-12 15:33:16]
  • 评测
  • 测评结果:WA
  • 用时:515ms
  • 内存:17076kb
  • [2023-08-12 15:31:01]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

void just_do_it();

int main() {
	#ifdef KAMIRULEZ
		freopen("kamirulez.inp", "r", stdin);
		freopen("kamirulez.out", "w", stdout);
	#endif
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	just_do_it();
	return 0;
}

const int inf = 1e9 + 20;

struct edge {
	int x, y, w, i, j;

	edge(int _x, int _y, int _w): x(_x), y(_y), w(_w) {};

	edge(int _x, int _y, int _i, int _j): x(_x), y(_y), w(_y - _x), i(_i), j(_j) {};

	edge(int _x, int _y, int _w, int _i, int _j): x(_x), y(_y), w(_w), i(_i), j(_j) {};
};

long long encode(int x, int y) {
	return ((long long)x << 32) | y;
}

bool operator<(edge e1, edge e2) {
	if (e1.w != e2.w) {
		return e1.w < e2.w;
	}
	else {
		return encode(e1.x, e1.y) < encode(e2.x, e2.y);
	}
}

long long match(vector<int> &ranges, vector<int> &color, vector<edge> &edges, unordered_set<long long> &hashes) {
	int color_cnt = *max_element(color.begin(), color.end()) + 1;
	vector<edge> best(color_cnt, edge(-1, -1, inf));
	for (auto e: edges) {
		int x = e.x;
		int y = e.y;
		int w = e.w;
		int i = upper_bound(ranges.begin(), ranges.end(), x) - ranges.begin() - 1;
		int j = upper_bound(ranges.begin(), ranges.end(), y) - ranges.begin() - 1;
		if (color[i] != color[j]) {
			best[color[i]] = min(best[color[i]], edge(x, y, w, i, j));
			best[color[j]] = min(best[color[j]], edge(x, y, w, i, j));
		}
	}
	int range_cnt = (int)ranges.size() - 1;
	for (int iter = 0; iter < 2; iter++) {
		for (int id = 0; id < range_cnt - 1; id++) {
			set<edge> cand;
			cand.emplace(ranges[id + 1] - 1, ranges[id + 1], id, id + 1);
			while (!cand.empty()) {
				int x = cand.begin()->x;
				int y = cand.begin()->y;
				int i = cand.begin()->i;
				int j = cand.begin()->j;
				if (hashes.find(encode(x, y)) == hashes.end()) {
					best[color[i]] = min(best[color[i]], *cand.begin());
					best[color[j]] = min(best[color[j]], *cand.begin());
					break;
				}
				cand.erase(cand.begin());
				if (x > ranges[i]) {
					cand.emplace(x - 1, y, i, j);
				}
				else if (iter == 1 && i > 0) {
					if (color[i - 1] != color[j]) {
						cand.emplace(x - 1, y, i - 1, j);
					}
					else if (i > 1) {
						cand.emplace(ranges[i - 1] - 1, y, i - 2, j);
					}
				}
				if (y + 1 < ranges[j + 1]) {
					cand.emplace(x, y + 1, i, j);
				}
				else if (iter == 0 && j + 1 < range_cnt) {
					if (color[j + 1] != color[i]) {
						cand.emplace(x, y + 1, i, j + 1);
					}
					else if (j + 2 < range_cnt) {
						cand.emplace(x, ranges[j + 2], i, j + 2);
					}
				}
			}
		}
	}
	vector<int> dsu_par(color_cnt, -1);
	vector<int> dsu_depth(color_cnt, 0);
	long long res = 0;
	for (int u = 0; u < color_cnt; u++) {
		int w = best[u].w;
		assert(w < inf);
		int v = color[best[u].i] ^ color[best[u].j] ^ u;
		int ru = u;
		while (dsu_par[ru] != -1) {
			ru = dsu_par[ru];
		}
		int rv = v;
		while (dsu_par[rv] != -1) {
			rv = dsu_par[rv];
		}
		if (ru == rv) {
			continue;
		}
		if (dsu_depth[ru] > dsu_depth[rv]) {
			swap(ru, rv);
		}
		if (dsu_depth[ru] == dsu_depth[rv]) {
			dsu_depth[rv]++;
		}
		dsu_par[ru] = rv;
		res += w;
	}
	for (int i = 0; i < range_cnt; i++) {
		int u = color[i];
		while (dsu_par[u] != -1) {
			u = dsu_par[u];
		}
		color[i] = u;
	}
	return res;
}

void join(vector<int> &ranges, vector<int> &color) {
	int range_cnt = (int)ranges.size() - 1;
	vector<int> color_id(range_cnt);
	vector<int> nxt_ranges, nxt_color;
	for (int i = 0; i < range_cnt; i++) {
		if (nxt_color.empty() || nxt_color.back() != color[i]) {
			nxt_ranges.push_back(ranges[i]);
			nxt_color.push_back(color[i]);
			color_id[color[i]] = 1;
		}
	}
	for (int i = 1; i < range_cnt; i++) {
		color_id[i] += color_id[i - 1];
	}
	ranges.swap(nxt_ranges);
	color.swap(nxt_color);
	for (auto &x: color) {
		x = color_id[x] - 1;
	}
}

void test() {
	int n, m;
	cin >> n >> m;
	vector<edge> edges;
	unordered_set<long long> hashes;
	vector<int> ranges;
	ranges.push_back(1);
	ranges.push_back(n + 1);
	for (int i = 0; i < m; i++) {
		int x, y, w;
		cin >> x >> y >> w;
		edges.emplace_back(x, y, w);
		ranges.push_back(x);
		ranges.push_back(x + 1);
		hashes.insert(encode(x, y));
	}
	sort(ranges.begin(), ranges.end());
	ranges.erase(unique(ranges.begin(), ranges.end()), ranges.end());
	int range_cnt = (int)ranges.size() - 1;
	vector<int> color(range_cnt);
	for (int i = 0; i < range_cnt; i++) {
		color[i] = i;
	}
	long long res = n - range_cnt;
	if (range_cnt == 1) {
		cout << res << '\n';
		return;
	}
	while (true) {
		res += match(ranges, color, edges, hashes);
		join(ranges, color);
		if ((int)ranges.size() == 1) {
			break;
		}
		ranges.push_back(n + 1);
	}
	cout << res << '\n';
}

void just_do_it() {
	int t;
	cin >> t;
	for (int i = 0; i < t; i++) {
		test();
	}
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 3468kb

input:

3
5 3
1 2 5
2 3 4
1 5 0
5 0
5 4
1 2 1000000000
1 3 1000000000
1 4 1000000000
1 5 1000000000

output:

4
4
1000000003

result:

ok 3 number(s): "4 4 1000000003"

Test #2:

score: -100
Wrong Answer
time: 515ms
memory: 17076kb

input:

16
1000000000 0
447 99681
1 2 1000000000
1 3 1000000000
2 3 1000000000
1 4 1000000000
2 4 1000000000
3 4 1000000000
1 5 1000000000
2 5 1000000000
3 5 1000000000
4 5 1000000000
1 6 1000000000
2 6 1000000000
3 6 1000000000
4 6 1000000000
5 6 1000000000
1 7 1000000000
2 7 1000000000
3 7 1000000000
4 7 ...

output:

999999999
446000000000
732256441
999999680
999899999
999966830
245
30
2382
1785
1367
5141
46
709
905
38

result:

wrong answer 7th numbers differ - expected: '127', found: '245'