結果

問題 No.529 帰省ラッシュ
ユーザー QCFiumQCFium
提出日時 2020-01-29 19:08:10
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
RE  
実行時間 -
コード長 5,064 bytes
コンパイル時間 2,594 ms
コンパイル使用メモリ 200,104 KB
実行使用メモリ 52,292 KB
最終ジャッジ日時 2023-10-14 06:45:22
合計ジャッジ時間 9,133 ms
ジャッジサーバーID
(参考情報)
judge15 / judge12
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,352 KB
testcase_01 AC 2 ms
4,356 KB
testcase_02 AC 2 ms
4,368 KB
testcase_03 AC 1 ms
4,348 KB
testcase_04 RE -
testcase_05 RE -
testcase_06 RE -
testcase_07 RE -
testcase_08 RE -
testcase_09 RE -
testcase_10 WA -
testcase_11 WA -
testcase_12 RE -
testcase_13 AC 255 ms
52,292 KB
testcase_14 AC 223 ms
24,360 KB
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

int ri() {
	int n;
	scanf("%d", &n);
	return n;
}

struct TwoDecomp {
	std::vector<std::vector<int> > hen;
	TwoDecomp (const std::vector<std::vector<int> > &hen) : hen(hen) {}
	std::vector<int> low, ord;
	std::vector<bool> used;
	int dfs_cnt = 0;
	void dfs(int i, int prev) {
		ord[i] = dfs_cnt++;
		low[i] = ord[i];
		for (auto j :hen[i]) {
			if (!used[j]) {
				used[j] = true;
				dfs(j, i);
				low[i] = std::min(low[i], low[j]);
			} else if (j != prev) low[i] = std::min(low[i], low[j]);
		}
	}
	std::pair<std::vector<int>, std::vector<std::vector<int> > > decomp() {
		int n = hen.size();
		low.resize(n);
		ord.resize(n);
		used.resize(n);
		used[0] = true;
		dfs(0, -1);
		used.assign(n, false);
		std::vector<int> group(n);
		int group_cnt = 0;
		for (int i = 0; i < n; i++) {
			if (used[i]) continue;
			used[i] = true;
			std::queue<int> que;
			que.push(i);
			while (que.size()) {
				int cur = que.front();
				group[cur] = group_cnt;
				que.pop();
				for (auto j : hen[cur]) {
					if (used[j] || low[j] > ord[i]) continue;
					used[j] = true;
					que.push(j);
				}
			}
			group_cnt++;
		}
		std::vector<std::vector<int> > new_hen(group_cnt);
		for (int i = 0; i < n; i++) for (auto j : hen[i]) if (group[i] != group[j]) {
			new_hen[group[i]].push_back(group[j]);
		}
		return {group, new_hen};
	}
};

struct SegTree {
	std::vector<std::priority_queue<int> > leaf;
	std::vector<std::pair<int, int> > max;
	int n;
	SegTree () = default;
	SegTree (int n_) {
		for (n = 1; n < n_; n <<= 1);
		leaf.resize(n);
		max.resize(n << 1, {-1, -1});
	}
	void push(int i, int val) {
		leaf[i].push(val);
		for (max[i + n] = {leaf[i].size() ? leaf[i].top() : -1, i}, i += n; i >>= 1; )
			max[i] = std::max(max[i << 1], max[i << 1 | 1]);
	}
	int pop(int i) {
		int val = leaf[i].top();
		leaf[i].pop();
		for (max[i + n] = {leaf[i].size() ? leaf[i].top() : -1, i}, i += n; i >>= 1; )
			max[i] = std::max(max[i << 1], max[i << 1 | 1]);
		return val;
	}
	std::pair<int, int> get_max(int l, int r) {
		int val = -1, index = -1;
		for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
			if (r & 1) {
				r--;
				if (val < max[r].first) val = max[r].first, index = max[r].second;
			}
			if (l & 1) {
				if (val < max[l].first) val = max[l].first, index = max[l].second;
				l++;
			}
		}
		return {index, val};
	}
};

struct HLDecomp {
	std::vector<std::vector<int> > hen;
	HLDecomp (const std::vector<std::vector<int> > &hen) : hen(hen) {}
	std::vector<int> size, parent;
	void dfs1(int i, int prev) {
		parent[i] = prev;
		if (prev != -1) hen[i].erase(std::find(hen[i].begin(), hen[i].end(), prev));
		for (auto &j : hen[i]) {
			dfs1(j, i);
			size[i] += size[j];
			if (size[j] > size[hen[i][0]]) std::swap(j, hen[i][0]);
		}
	}
	std::vector<int> top, chain, depth_local, chain_sizes{0};
	void dfs2(int i) {
		chain[i] = chain_sizes.size() - 1;
		depth_local[i] = chain_sizes.back()++;
		for (auto j :hen[i]) {
			if (j == hen[i][0]) top[j] = top[i];
			else top[j] = j, chain_sizes.push_back(0);
			dfs2(j);
		}
	}
	std::vector<SegTree> trees;
	void decomp() {
		int n = hen.size();
		size.resize(n, 1);
		parent.resize(n);
		dfs1(0, -1);
		top.resize(n);
		chain.resize(n);
		depth_local.resize(n);
		dfs2(0);
		int m = chain_sizes.size();
		trees.resize(m);
		for (int i = 0; i < m; i++) trees[i] = SegTree(chain_sizes[i]);
	}
	void push(int i, int val) {
		trees[chain[i]].push(depth_local[i], val);
	}
	int pop(int i, int j) {
		int max = -1, max_chain = -1, max_depth = -1;
		while (chain[i] > chain[j]) {
			auto tmp = trees[chain[i]].get_max(0, depth_local[i] + 1);
			if (max < tmp.second) max = tmp.second, max_chain = chain[i], max_depth = tmp.first;
			i = parent[top[i]];
		}
		while (chain[i] < chain[j]) {
			auto tmp = trees[chain[j]].get_max(0, depth_local[j] + 1);
			if (max < tmp.second) max = tmp.second, max_chain = chain[j], max_depth = tmp.first;
			j = parent[top[j]];
		}
		while (chain[i] > chain[j]) {
			auto tmp = trees[chain[i]].get_max(0, depth_local[i] + 1);
			if (max < tmp.second) max = tmp.second, max_chain = chain[i], max_depth = tmp.first;
			i = parent[top[i]];
		}
		if (depth_local[i] > depth_local[j]) std::swap(i, j);
		auto tmp = trees[chain[i]].get_max(depth_local[i], depth_local[j] + 1);
		if (max < tmp.second) max = tmp.second, max_chain = chain[i], max_depth = tmp.first;
		
		if (max == -1) return -1;
		trees[max_chain].pop(max_depth);
		return max;
	}
};

int main() {
	int n = ri(), m = ri(), q = ri();
	std::vector<std::vector<int> > org_hen(n);
	for (int i = 0; i < m; i++) {
		int a = ri() - 1;
		int b = ri() - 1;
		org_hen[a].push_back(b);
		org_hen[b].push_back(a);
	}
	TwoDecomp two_decomper(org_hen);
	auto decomped = two_decomper.decomp();
	auto group = decomped.first;
	auto hen = decomped.second;
	
	HLDecomp hl_decomper(hen);
	hl_decomper.decomp();
	for (int i = 0; i < q; i++) {
		int t = ri();
		int x = ri();
		int y = ri();
		if (t == 1) hl_decomper.push(group[x - 1], y);
		else printf("%d\n", hl_decomper.pop(group[x - 1], group[y - 1]));
	}
	return 0;
}
0