#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;
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);
}
dfs(1, 1);
set<intt> pos[n + 1];
for(intt i = 1; i <= k; i++){
cin >> a[i];
isin[a[i]] = i;
}
vector<intt> ls(n+1,0ll);
for(intt i = 1; i <= k - 1; i++){
intt l = lca(a[i], a[i+1]);
// cout << l << ' ';
pos[l].insert(i);
ls[i] = l;
}
// cout << endl;
while(q--) {
intt t;
cin >> t;
if(t == 1) {
intt idx, v;
cin >> idx >> v;
isin[a[idx]] = 0;
a[idx] = v;
isin[a[idx]] = idx;
if(idx != 1) {
intt pl = ls[idx-1], nl = lca(a[idx-1], a[idx]);
pos[pl].erase(idx-1);
ls[idx-1] = nl;
pos[nl].insert(idx-1);
}
if(idx != k) {
intt pl = ls[idx], nl = lca(a[idx], a[idx+1]);
pos[pl].erase(idx);
ls[idx] = nl;
pos[nl].insert(idx);
}
} else {
intt l, r, v;
cin >> l >> r >> v;
--l; --r;
if(isin[v]) {
cout << l + 1 << " " << r + 1 << endl;
continue;
}
auto itl = pos[v].lower_bound(l);
// cout << v << ": ";
// for(intt i : pos[v]) cout << i << ' ';
// cout << endl << v << ": ";
// for(intt i = 1; i <= k - 1; i++) cout << ls[i] << ' ';
// cout << endl;
if(itl == pos[v].end()) {
cout << -1 << " " << -1 << endl;
continue;
}
intt indl = *itl;
if(indl <= r){
cout << indl << " " << indl + 1 << endl;
} else {
cout << -1 << " " << -1 << endl;
}
}
}
}
signed main() {
SPEED;
intt tst = 1;
// cin >> tst;
while (tst--) {
solve();
}
}
// lca(a, b, c, d, ... , z) her hansisa adjacent iki node-un lca-sina beraber olmalidi?
# | 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... |