답안 #906133

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
906133 2024-01-13T14:31:16 Z MilosMilutinovic Prize (CEOI22_prize) C++14
54 / 100
3500 ms 840532 KB
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
using pi = array<int, 2>;
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
const int MAX = 2050000;
 
int n, k, q, t, r1, r2;
int a[MAX], b[MAX], c[MAX], d[MAX];
vector<int> ids;
 
namespace tree1 {
	int dep[MAX], logs[MAX], p[MAX];
	pair<int, int> st[MAX][20];
	vector<int> gph[MAX];
	vector<pi> adj[MAX];
	vector<pair<int, int>> euler;
	lint dist[MAX];
	bool seen[MAX];
	void add(int u, int v) {
		gph[u].push_back(v);
		gph[v].push_back(u);
	}
	void dfs(int x, int px) {
		if (sz(ids) < k) {
			ids.push_back(x);
		}
		dep[x] = dep[px] + 1;
		p[x] = sz(euler);
		euler.push_back({dep[x], x});
		for (auto& y : gph[x]) {
			if (y == px) continue;
			dfs(y, x);
			euler.push_back({dep[x], x});
		}
	}
	int getlca(int s, int e) {
		if (p[s] > p[e]) swap(s, e);
		int k = logs[p[e] - p[s] + 1];
		return min(st[p[s]][k], st[p[e] - (1 << k) + 1][k]).second;
	}
	void dfs(int x) {
		seen[x] = true;
		for (auto& y : adj[x]) {
			if (seen[y[0]]) continue;
			dist[y[0]] = dist[x] + y[1];
			dfs(y[0]);
		}
	}
	void build() {
		for (int i = 2; i < MAX; i++) 
			logs[i] = logs[i >> 1] + 1;
		for (int i = 0; i < sz(euler); i++)
			st[i][0] = euler[i];
		for (int j = 1; j < 20; j++)
			for (int i = 0; i + (1 << j) <= sz(euler); i++)
				st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
		for (int i = 0; i + 1 < k; i++) {
			int x = ids[i];
			int y = ids[i + 1];
			int z = getlca(ids[i], ids[i + 1]);
			adj[x].push_back({z, -a[i]});
			adj[z].push_back({x, a[i]});
			adj[y].push_back({z, -b[i]});
			adj[z].push_back({y, b[i]});
		}
		dfs(r1);
	}
	lint query(int x, int y) {
		return dist[x] + dist[y] - 2 * dist[getlca(x, y)];
	}
};
 
namespace tree2 {
	int dfn[MAX], T, dep[MAX], par[20][MAX];
	vector<int> gph[MAX];
	vector<pi> adj[MAX];
	lint dist[MAX];
	bool seen[MAX];
	void add(int u, int v) {
		gph[u].push_back(v);
		gph[v].push_back(u);
	}
	void dfs(int x, int px) {
		dfn[x] = ++T;
		dep[x] = dep[px] + 1;
		par[0][x] = px;
		for (int i = 1; i < 20; i++) 
			par[i][x] = par[i - 1][par[i - 1][x]];
		for (auto& y : gph[x]) {
			if (y == px) continue;
			dfs(y, x);
		}
	}
	int getlca(int s, int e) {
		if (dep[s] < dep[e]) swap(s, e);
		for (int i = 19; i >= 0; i--)
			if (dep[par[i][s]] >= dep[e])
				s = par[i][s];
		if (s == e) return s;
		for (int i = 19; i >= 0; i--)
			if (par[i][s] != par[i][e])
				s = par[i][s], e = par[i][e];
		return par[0][s];
	}
	void order() {
		sort(all(ids), [&](int i, int j) { return dfn[i] < dfn[j]; });
	}
	void dfs(int x) {
		seen[x] = true;
		for (auto& y : adj[x]) {
			if (seen[y[0]]) continue;
			dist[y[0]] = dist[x] + y[1];
			dfs(y[0]);
		}
	}
	void build() {
		for (int i = 0; i + 1 < k; i++) {
			int x = ids[i];
			int y = ids[i + 1];
			int z = getlca(ids[i], ids[i + 1]);
			adj[x].push_back({z, -c[i]});
			adj[z].push_back({x, c[i]});
			adj[y].push_back({z, -d[i]});
			adj[z].push_back({y, d[i]});
		}
		vector<int> ord(n);
		iota(all(ord), 0);
		sort(all(ord), [&](int i, int j) { return dfn[i] < dfn[j]; });
		for (int x : ord) if (!seen[x]) dfs(x);
	}
	lint query(int x, int y) {
		return dist[x] + dist[y] - 2 * dist[getlca(x, y)];
	}
};
 
int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> k >> q >> t;
	for (int i = 0; i < n; i++) {
		int p;
		cin >> p;
		if (p == -1) {
			r1 = i;
		} else {
			--p;
			tree1::add(i, p);
		}
	}
	for (int i = 0; i < n; i++) {
		int p;
		cin >> p;
		if (p == -1) {
			r2 = i;
		} else {
			--p;
			tree2::add(i, p);
		}
	}
	tree1::dfs(r1, r1);
	tree2::dfs(r2, r2);
	tree2::order();
	for (int i = 0; i < k; i++) {
		cout << ids[i] + 1 << " ";
	}
	cout << "\n";
	for (int i = 0; i + 1 < k; i++) {
		cout << "? " << ids[i] + 1 << " " << ids[i + 1] + 1 << "\n";
	}
	cout << "!" << endl;
	for (int i = 0; i + 1 < k; i++) {
		cin >> a[i] >> b[i] >> c[i] >> d[i];
	}
	tree1::build();
	tree2::build();
	vector<int> x(t), y(t);
	for (int i = 0; i < t; i++) {
		cin >> x[i] >> y[i];
		--x[i]; --y[i];
	}
	for (int i = 0; i < t; i++) {
		cout << tree1::query(x[i], y[i]) << " " << tree2::query(x[i], y[i]) << "\n";
	}
	cout << endl;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 2380 ms 556696 KB Output is correct
2 Correct 2550 ms 558864 KB Output is correct
3 Correct 2172 ms 521084 KB Output is correct
4 Correct 1975 ms 521528 KB Output is correct
5 Correct 2145 ms 522848 KB Output is correct
6 Correct 2421 ms 528848 KB Output is correct
7 Correct 2455 ms 528880 KB Output is correct
8 Correct 2398 ms 526384 KB Output is correct
9 Correct 2106 ms 520204 KB Output is correct
10 Correct 2221 ms 523652 KB Output is correct
11 Correct 1974 ms 518400 KB Output is correct
12 Correct 2142 ms 520708 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2445 ms 558836 KB Output is correct
2 Correct 2413 ms 556556 KB Output is correct
3 Correct 2033 ms 520912 KB Output is correct
4 Correct 2256 ms 523364 KB Output is correct
5 Correct 2154 ms 521276 KB Output is correct
6 Correct 2341 ms 524836 KB Output is correct
7 Correct 2592 ms 529496 KB Output is correct
8 Correct 2781 ms 529348 KB Output is correct
9 Correct 2541 ms 526948 KB Output is correct
10 Correct 2560 ms 528784 KB Output is correct
11 Correct 2509 ms 520076 KB Output is correct
12 Correct 2643 ms 518416 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1579 ms 550432 KB Output is correct
2 Correct 1570 ms 548488 KB Output is correct
3 Correct 1399 ms 465476 KB Output is correct
4 Correct 1468 ms 503312 KB Output is correct
5 Correct 1330 ms 510076 KB Output is correct
6 Correct 1564 ms 462504 KB Output is correct
7 Correct 1611 ms 508688 KB Output is correct
8 Correct 1554 ms 516320 KB Output is correct
9 Correct 1512 ms 514868 KB Output is correct
10 Correct 1645 ms 472828 KB Output is correct
11 Correct 1679 ms 486888 KB Output is correct
12 Correct 1696 ms 512460 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 3532 ms 840532 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 3525 ms 819964 KB Time limit exceeded
2 Halted 0 ms 0 KB -