Submission #1300075

#TimeUsernameProblemLanguageResultExecution timeMemory
1300075lex._.Birthday gift (IZhO18_treearray)C++20
100 / 100
471 ms77188 KiB
#include <bits/stdc++.h> #define NMAX 200001 #define LOG 20 using namespace std; int n, m, q; vector<int> muchii[NMAX]; ///muchiile arborelui int nivel[NMAX]; ///nivelul fiecarui nod int stra[LOG][NMAX]; ///stra[e][i] = al e-lea stramos al nodului i void dfs(int nod, int tata) ///salvam tatal fiecarui nod { stra[0][nod]=tata; nivel[nod]=1+nivel[tata]; for(auto& fiu : muchii[nod]) { if(fiu!=tata) dfs(fiu, nod); } } void precalc() ///precalculam structura de date stra { for(int e=1; e<LOG; e++) { for(int i=1; i<=n; i++) stra[e][i]=stra[e-1][stra[e-1][i]]; } } int up(int nod, int k) ///al k-lea stramos al lui nod { for(int e=LOG-1; e>=0; e--) { if((1<<e)<=k) { nod=stra[e][nod]; k-=(1<<e); } } return nod; } int LCA(int nod1, int nod2) ///LCA-ul a doua noduri { if(nivel[nod1]<nivel[nod2]) swap(nod1, nod2); if(nod2==0) return nod1; nod1=up(nod1, nivel[nod1]-nivel[nod2]); ///il aducem pe nod1 la nivelul nodului nod2 if(nod1==nod2) return nod1; for(int e=LOG-1; e>=0; e--) ///cautam binar ultimul stramos al fiecarui nod care nu este comun { if(stra[e][nod1]!=stra[e][nod2]) { nod1=stra[e][nod1]; nod2=stra[e][nod2]; } } return stra[0][nod1]; } int a[NMAX]; int lca_a[NMAX]; ///LCA-ul a doua numere situate pe pozitii consecutive in a set<int> pozitii_a[NMAX]; ///pozitiile pe care se afla fiecare valoare in a set<int> pozitii_lca[NMAX]; ///pozitiile pe care se afla fiecare valoare in lca_a int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m >> q; for(int i=1; i<=n-1; i++) { int u, v; cin >> u >> v; muchii[u].push_back(v); muchii[v].push_back(u); } dfs(1, 0); precalc(); for(int i=1; i<=m; i++) { cin >> a[i]; pozitii_a[a[i]].insert(i); } for(int i=1; i<=m; i++) { ///daca exista un interval in [l, r] care are LCA-ul v, atunci fie exista doua pozitii consecutive cu LCA-ul v, fie v se afla in interval ///astfel, avem nevoie doar de LCA-ul numerelor aflate pe pozitii consecutive lca_a[i]=LCA(a[i], a[i+1]); pozitii_lca[lca_a[i]].insert(i); } while(q--) { int tip; cin >> tip; if(tip==1) { int pos, v; cin >> pos >> v; pozitii_a[a[pos]].erase(pos); if(pos>1) pozitii_lca[lca_a[pos-1]].erase(pos-1); pozitii_lca[lca_a[pos]].erase(pos); a[pos]=v; if(pos>1) lca_a[pos-1]=LCA(a[pos-1], a[pos]); lca_a[pos]=LCA(a[pos], a[pos+1]); pozitii_a[a[pos]].insert(pos); if(pos>1) pozitii_lca[lca_a[pos-1]].insert(pos-1); pozitii_lca[lca_a[pos]].insert(pos); } else { int l, r, v; cin >> l >> r >> v; if(pozitii_a[v].lower_bound(l)!=pozitii_a[v].end() && (*pozitii_a[v].lower_bound(l))<=r) ///cautam prima pozitie a lui v situata dupa l; daca aceasta este mai mica sau egala cu r, atunci luam intervalul [x, x] { int x=(*pozitii_a[v].lower_bound(l)); cout << x << " " << x << "\n"; } else if(pozitii_lca[v].lower_bound(l)!=pozitii_lca[v].end() && (*pozitii_lca[v].lower_bound(l))<=r-1) ///cautam prima pozitie a lui v ca LCA situata dupa l; daca aceasta este mai mica sau egala cu r-1, atunci luam intervalul [x, x+1] { int x=(*pozitii_lca[v].lower_bound(l)); cout << x << " " << x+1 << "\n"; } else { cout << -1 << " " << -1 << "\n"; } } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...