Submission #556731

#TimeUsernameProblemLanguageResultExecution timeMemory
556731RaresFelixInside information (BOI21_servers)C++17
50 / 100
378 ms67992 KiB
#include <bits/stdc++.h> #define MN 120071 #define MK 20 using namespace std; int n, k; vector<pair<int, int> > L0[MN]; vector<int> L[MN]; vector<tuple<int, int, int, int> > Queries; namespace BASIC { int Niv[MN], Val[MN], Par[MN], NiceUp[MN]; int Maxi[MK][MN], Nice[2][MK][MN], Stramos[MK][MN]; void init() { ///aleg rad arbitrar in 1 function<void(int, int, int, int)> dfs0 = [&](int u, int p, int niv, int val) { Val[u] = val; Niv[u] = niv; Par[u] = p; for(auto &[it, w] : L0[u]) if(it != p) { dfs0(it, u, niv + 1, w); } if(Niv[u] > 1) NiceUp[u] = Val[u] < Val[p]; }; dfs0(1, 0, 0, 0); for(int i = 1; i <= n; ++i) Stramos[0][i] = Par[i]; for(int k = 1; k < MK; ++k) { for(int i = 1; i <= n; ++i) Stramos[k][i] = Stramos[k-1][Stramos[k-1][i]]; } for(int i = 1; i <= n; ++i) Nice[0][0][i] = NiceUp[i] ^ 1, Nice[1][0][i] = NiceUp[i]; for(int d = 0; d < 2; ++d) { for(int k = 1; k < MK; ++k) { for(int i = 1; i <= n; ++i) { Nice[d][k][i] = Nice[d][k-1][i] & Nice[d][k-1][Stramos[k-1][i]]; } } } for(int i = 1; i <= n; ++i) Maxi[0][i] = Val[i]; for(int k = 1; k < MK; ++k) for(int i = 1; i <= n; ++i) Maxi[k][i] = max(Maxi[k-1][i], Maxi[k-1][Stramos[k-1][i]]); } bool is_okay(int u, int v) { ///!!! ORDER IS VERY IMPORTANT U => V bool rez = 1; if(Niv[u] > Niv[v]) { for(int k = MK - 1; k >= 0; --k) { if((Niv[u] - Niv[v] - 1) & (1 << k)) { rez &= Nice[1][k][u]; u = Stramos[k][u]; } } if(Par[u] != v) rez &= Nice[1][0][u]; u = Par[u]; } else if (Niv[u] < Niv[v]) { for(int k = MK - 1; k >= 0; --k) { if((Niv[v] - Niv[u] - 1) & (1 << k)) { rez &= Nice[0][k][v]; // printf("debug %d %d %d -- ", k, v, rez); //printf("debug %d %d %d\n", Nice[0][0][v], Nice[0][1][v], Stramos[1][v]); v = Stramos[k][v]; } } if(Par[v] != u) rez &= Nice[0][0][v]; v = Par[v]; } ///acum sunt la acelasi nivel assert(Niv[u] == Niv[v]); if(v == u || !rez) return rez; for(int k = MK - 1; k >= 0; --k) { if(Stramos[k][u] != Stramos[k][v]) { rez &= Nice[0][k][v]; rez &= Nice[1][k][u]; v = Stramos[k][v]; u = Stramos[k][u]; } } if(u != v) rez &= Val[u] < Val[v]; return rez; } int max_on_path(int u, int v) { int rez = 0; if(Niv[u] < Niv[v]) swap(u, v); if(Niv[u] != Niv[v]) for(int k = MK - 1; k >= 0; --k) if((Niv[u] - Niv[v] - 1) & (1 << k)) { rez = max(rez, Maxi[k][u]); u = Stramos[k][u]; } if(Niv[u] != Niv[v]) { rez = max(rez, Maxi[0][u]); u = Par[u]; } assert(Niv[u] == Niv[v]); for(int k = MK - 1; k >= 0; --k) if(Stramos[k][u] != Stramos[k][v]) { rez = max(rez, Maxi[k][u]); rez = max(rez, Maxi[k][v]); u = Stramos[k][u]; v = Stramos[k][v]; } if(u != v) rez = max({rez, Val[u], Val[v]}); return rez; } } int main() { //cin.tie(0)->sync_with_stdio(0); cin >> n >> k; for(int i = 1, a, b; i <= n + k - 1; ++i) { char tip; cin >> tip; if(tip == 'S') { cin >> a >> b; L0[a].push_back({b, i}); L0[b].push_back({a, i}); } else if(tip == 'Q') { cin >> a >> b; Queries.push_back({0, a, b, i}); } else { cin >> a; Queries.push_back({1, a, 0, i}); } } BASIC::init(); for(auto &[tip, a, b, id] : Queries) { if(tip == 0) { int ok = BASIC::is_okay(b, a); ok &= BASIC::max_on_path(b, a) < id; cout << (ok ? "yes\n" : "no\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...