#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
using namespace std;
// using namespace __gnu_pbds;
// template<class T>
// using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define SPEED \
ios_base::sync_with_stdio(0); \
cin.tie(NULL); \
cout.tie(NULL);
#define pb push_back
#define ins insert
#define fi first
#define se second
// #define endl "\n"
#define ALL(x) x.begin(), x.end()
#define sz(x) x.size()
#define intt long long
const intt mod = 1e9 + 7;
const intt base = 31;
const intt inf = 1e18;
const intt mxN = 2e5 + 5;
const intt L = 18;
vector<vector<intt>> graph, up;
vector<intt> in(mxN), out(mxN), a(mxN), isin(mxN);
intt timer, n, k, q;
multiset<intt> st[mxN];
void dfs(intt node, intt parent) {
in[node] = timer++;
up[0][node] = parent;
for(intt i = 1; i <= L; i++) {
up[i][node] = up[i-1][up[i-1][node]];
}
for(auto u : graph[node]) {
if(u != parent) {
dfs(u, node);
}
}
out[node] = timer++;
}
bool isata(intt a, intt b) {
return in[a] <= in[b] && out[a] >= out[b];
}
intt lca(intt a, intt b) {
if(isata(a, b)) return a;
if(isata(b, a)) return b;
for(intt i = L - 1; i >= 0; i--) {
if(!isata(up[i][a], b)) {
a = up[i][a];
}
}
return up[0][a];
}
void solve() {
cin >> n >> k >> q;
graph.assign(n + 1, vector<intt> {});
up.assign(L + 1, vector<intt>(n + 1, 0ll));
for(intt i = 1; i <= n - 1; i++) {
intt a, b;
cin >> a >> b;
graph[a].pb(b);
graph[b].pb(a);
}
for(intt i = 1; i <= k; i++) {
cin >> a[i];
}
// cout << "ASJKFASFAS" << endl;
dfs(1, 1);
vector<intt> lcalar(k + 2);
multiset<intt> mst;
for(intt i = 1; i <= k - 1; i++) {
intt l = lca(a[i], a[i+1]);
mst.insert(l);
st[l].insert(i);
lcalar[i] = l;
}
// for(intt i = 1; i <= k - 1; i++) {
// cout << lcalar[i] << " ";
// }
// cout << endl;
// l1, l2, l3;
// 1, 4, 3, 2
while(q--) {
intt type;
cin >> type;
if(type == 1) {
intt pos, v;
cin >> pos >> v;
if(pos != 1){
intt soll = lcalar[pos-1];
st[soll].erase(st[soll].find(pos-1));
intt newl = lca(v, a[pos-1]);
st[newl].insert(pos-1);
lcalar[pos-1] = newl;
}
if(pos != k) {
intt sagl = lcalar[pos];
st[sagl].erase(st[sagl].find(pos));
intt newl = lca(v, a[pos+1]);
st[newl].insert(pos);
lcalar[pos] = newl;
}
} else{
intt l, r, v;
cin >> l >> r >> v;
// cout << "LCALAR: ";
// for(intt i = 1; i <= k - 1; i++) cout << lcalar[i] << " ";
// cout << endl;
// cout << v << ": ";
// for(intt i : st[v]) cout << i << " ";
// cout<< endl;
if(st[v].empty()) {
cout << -1 << " " << -1 << endl;
continue;
}
auto it = st[v].lower_bound(l-1);
auto itt = prev(st[v].upper_bound(r-1));
intt num = *it;
intt num2 = *itt;
if(num <= num2) {
cout << *it + 1 << " " << *itt + 1 << endl;
} else {
cout << -1 << " " << -1 << endl;
}
}
}
}
signed main() {
SPEED;
intt tst = 1;
// cin >> tst;
while (tst--) {
solve();
}
}
// lca(a, b, c) onsuz ya lca(a,b) ya lca(b,c) dir de
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |