Submission #1084316

#TimeUsernameProblemLanguageResultExecution timeMemory
1084316xnqsBirthday gift (IZhO18_treearray)C++17
100 / 100
547 ms82568 KiB
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
#include <set>

int gs, x, q;
std::vector<std::vector<int>> adj_list;
int arr[200005];
int up[18][200005];
int depth[200005];
std::set<int> occurences1[200005]; // occurences of node i in arr
std::set<int> occurences2[200005]; // occurences of lca of any two consecutive nodes in arr

void dfs(int k, int p) {
	depth[k] = depth[p]+1;
	up[0][k] = p;
	for (int l = 1; l < 18; l++) {
		up[l][k] = up[l-1][up[l-1][k]];
	}

	for (const auto& i : adj_list[k]) {
		if (i!=p) {
			dfs(i,k);
		}
	}
}

int get_kth_ancestor(int node, int k) {
	while (k) {
		int lvl = 31-__builtin_clz(k);
		node = up[lvl][node];
		k ^= (1<<lvl);
	}
	return node;
}

int get_lca(int a, int b) {
	if (depth[a]>depth[b]) {
		std::swap(a,b);
	}

	b = get_kth_ancestor(b,depth[b]-depth[a]);

	for (int lvl = 17; a != b;) {
		while (lvl-1>=0&&up[lvl][a]==up[lvl][b]) {
			--lvl;
		}

		a = up[lvl][a];
		b = up[lvl][b];
	}

	return a;
}

int main() {
	std::ios_base::sync_with_stdio(false);
	std::cin.tie(NULL);
	std::cout.tie(NULL);

	std::cin >> gs >> x >> q;
	adj_list.resize(gs+1);
	for (int i = 0, a, b; i < gs-1; i++) {
		std::cin >> a >> b;
		adj_list[a].emplace_back(b);
		adj_list[b].emplace_back(a);
	}

	dfs(1,0);

	for (int i = 1; i <= x; i++) {
		std::cin >> arr[i];
		occurences1[arr[i]].emplace(i);
	}
	for (int i = 1; i+1 <= x; i++) {
		occurences2[get_lca(arr[i],arr[i+1])].emplace(i);
	}

	while (q--) {
		int op;
		std::cin >> op;
		if (op==1) {
			int pos, val;
			std::cin >> pos >> val;

			occurences1[arr[pos]].erase(pos);
			if (pos-1>=1) {
				occurences2[get_lca(arr[pos-1],arr[pos])].erase(pos-1);
			}
			if (pos+1<=x) {
				occurences2[get_lca(arr[pos],arr[pos+1])].erase(pos);
			}

			arr[pos] = val;
			occurences1[arr[pos]].emplace(pos);
			if (pos-1>=1) {
				occurences2[get_lca(arr[pos-1],arr[pos])].emplace(pos-1);
			}
			if (pos+1<=x) {
				occurences2[get_lca(arr[pos],arr[pos+1])].emplace(pos);
			}
		}
		else {
			int l, r, k;
			std::cin >> l >> r >> k;

			// if k itself pops up in [l, r]
			auto it = occurences1[k].lower_bound(l);
			if (it!=occurences1[k].end()&&*it<=r) {
				std::cout << (*it) << " " << (*it) << "\n";
				continue;
			}

			// if two consecutive occurences with lca k happen in [l, r]
			it = occurences2[k].lower_bound(l);
			if (it!=occurences2[k].end()&&(*it+1)<=r) {
				std::cout << (*it) << " " << (*it+1) << "\n";
				continue;
			}

			std::cout << "-1 -1\n";
		}
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...