제출 #721047

#제출 시각아이디문제언어결과실행 시간메모리
721047thimote75Birthday gift (IZhO18_treearray)C++14
100 / 100
1193 ms94400 KiB
#include <bits/stdc++.h> using namespace std; #define idata vector<int> #define graph vector<idata> #define sv vector<set<int>> const int MAX_K = 20; int nbNodes, seqSize, nbQuery; graph roads; idata depth; idata parents; graph parents_2k; void dfs (int node, int parent, int l_depth) { depth [node] = l_depth; parents [node] = parent; parents_2k[node][0] = parent; for (int next : roads[node]) if (next != parent) dfs(next, node, l_depth + 1); } void propagate () { for (int k = 0; k + 1 < MAX_K; k ++) { for (int i = 0; i < nbNodes; i ++) { if (parents_2k[i][k] == -1) continue ; parents_2k[i][k + 1] = parents_2k[parents_2k[i][k]][k]; } } } int jump (int n, int k) { for (int i = 0; i < MAX_K; i ++) if (((1 << i) & k) != 0) n = parents_2k[n][i]; return n; } int lca (int a, int b) { if (depth[a] > depth[b]) return lca(b, a); b = jump(b, depth[b] - depth[a]); if (a == b) return a; for (int i = MAX_K - 1; i >= 0; i --) { if (parents_2k[a][i] == parents_2k[b][i]) continue ; a = parents_2k[a][i]; b = parents_2k[b][i]; } if (a == b) return a; return parents[a]; } struct ITree { sv tree; idata seq; ITree () = default; ITree (int vec_space, int seq_size) { seq.resize(seq_size, -1); tree.resize(vec_space); } void modify (int index, int value) { if (seq[index] != -1) tree[seq[index]].erase(index); seq[index] = value; tree[value].insert(index); } int contains (int left, int right, int value) { auto &h = tree[value]; auto it = h.lower_bound(left); if (it == h.end()) return -1; int mu = *it; return mu <= right ? mu : -1; } }; idata sequence; ITree lca_sequence; ITree seq_search; void compute (int i) { lca_sequence.modify(i, lca(sequence[i], sequence[i + 1])); } int main () { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> nbNodes >> seqSize >> nbQuery; roads.resize(nbNodes); for (int iR = 1; iR < nbNodes; iR ++) { int a, b; cin >> a >> b; a --; b --; roads[a].push_back(b); roads[b].push_back(a); } depth .resize(nbNodes); parents .resize(nbNodes); parents_2k.resize(nbNodes, idata(MAX_K, -1)); dfs(0, -1, 0); propagate(); sequence.resize(seqSize); seq_search = ITree(nbNodes, seqSize); for (int i = 0; i < seqSize; i ++) { cin >> sequence[i]; sequence[i] --; seq_search.modify(i, sequence[i]); } lca_sequence = ITree(nbNodes, seqSize - 1); for (int i = 0; i + 1 < seqSize; i ++) compute(i); for (int iQ = 0; iQ < nbQuery; iQ ++) { int type, a, b, c; cin >> type >> a >> b; a --; b --; if (type == 2) { cin >> c; c --; int left = -1; int right = -1; int mu0 = lca_sequence.contains(a, b - 1, c); int mu1 = seq_search.contains(a, b, c); if (mu0 != -1) { left = mu0; right = mu0 + 1; } else if (mu1 != -1) { left = mu1; right = mu1; } if (left == -1) cout << "-1 -1\n"; else cout << left + 1 << " " << right + 1 << endl; } else { sequence[a] = b; seq_search.modify(a, b); if (a != 0) compute(a - 1); if (a != seqSize) compute(a); } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...