Submission #1264899

#TimeUsernameProblemLanguageResultExecution timeMemory
1264899Noname_1900Valley (BOI19_valley)C++20
0 / 100
56 ms26436 KiB
#include<bits/stdc++.h> using namespace std; const int NMAX = 100000; #define int long long int nbVilles, nbMagazins, nbRequetes, destination; struct T { int dest, temps, iArete, premDist; }; vector<T> chemins[NMAX]; bool magazin[NMAX]; //int trouverPlusProche() vector<int> traceLca; pair<int, int> posTrace[NMAX]; int iValNoeud; int noeudVersLca[NMAX]; int lcaVersNoeud[NMAX]; int profondeur[NMAX]; void parcours(int noeud, int anc) { if(anc == -1) { profondeur[noeud] = 1; } else profondeur[noeud] = profondeur[anc] +1; iValNoeud++; int valActu = iValNoeud; noeudVersLca[noeud] = valActu; lcaVersNoeud[valActu] = noeud; posTrace[valActu].first = traceLca.size(); posTrace[valActu].second = traceLca.size(); traceLca.push_back(valActu); for(auto pro : chemins[noeud]) { if(pro.dest == anc) continue; parcours(pro.dest, noeud); posTrace[valActu].second = traceLca.size(); traceLca.push_back(valActu); } } int arbreMin[NMAX*3]; pair<int, int> debFin[NMAX*3]; const int INFINI = 1e15; int construire(int noeud, int deb, int fin) { debFin[noeud] = {deb, fin}; if(deb == fin-1) return arbreMin[noeud] = traceLca[deb]; int mil = (deb+fin)/2; return arbreMin[noeud] = min(construire(noeud*2, deb, mil), construire(noeud*2+1, mil, fin)); } int trouverMin(int noeud, int deb, int fin) { // cout << "debArbre " << noeud << endl; if((debFin[noeud].first >= deb) && (debFin[noeud].second <= fin)) { // cout << noeud << " " << arbreMin[noeud] << "\n";; return arbreMin[noeud]; } if((debFin[noeud].first >= fin) || (debFin[noeud].second <= deb)) { // cout << noeud << " " << INFINI << "\n";; return INFINI; } int a = min(trouverMin(noeud*2, deb, fin), trouverMin(noeud*2+1, deb, fin)); // cout << noeud << " " << a << "\n";; return a; } pair<int, int> arrays[NMAX]; pair<int, int> plusHaut(int iArray) { int a = arrays[iArray].first, b = arrays[iArray].second; if(profondeur[a] < profondeur[b]) return {a, b}; return {b, a}; } bool liaison(int noeud, int ancetre) { int noeudLca = noeudVersLca[noeud], ancetreLca = noeudVersLca[ancetre]; int posNoeud = posTrace[noeudLca].first; int debA = posTrace[ancetreLca].first, finA = posTrace[ancetreLca].second; // cout << noeud << " a " << ancetre << ' ' << debA << " " << finA << " : " << posNoeud << endl; if((debA <= posNoeud) && (finA >= posNoeud)) return true; return false; } int lca(int noeud1, int noeud2) { // cout << noeud1 << " " << noeud2 << endl; noeud1 = noeudVersLca[noeud1]; noeud2 = noeudVersLca[noeud2]; int pos1 = posTrace[noeud1].first; int pos2 = posTrace[noeud2].first; // cout << noeud1 << " : " << pos1 << " " << noeud2 << " : " << pos2 << endl; int rep = trouverMin(1, min(pos1, pos2), max(pos1, pos2)+1); // cout << "rep lca : " << rep << endl; return lcaVersNoeud[rep]; } signed main() { ios::sync_with_stdio(false); cin.tie(0); iValNoeud = -1; cin >> nbVilles >> nbMagazins >> nbRequetes >> destination; --destination; for(int i = 0; i < nbVilles; i++) posTrace[i] = {-1, -1}; for(int i = 0; i < nbVilles-1; i++) { int a, b, t; cin >> a >> b >> t; --a; --b; chemins[a].push_back({b, t, i, 0}); chemins[b].push_back({a, t, i, 0}); arrays[i] = {a, b}; } for(int i = 0; i < nbMagazins; i++) { int a; cin >> a; --a; magazin[a] = true; } parcours(0, -1); // for(int i = 0; i < nbVilles; i++) cout << lcaVersNoeud[i] << " "; // for(int i : traceLca) cout << lcaVersNoeud[i]+1 << " "; // cout << endl; construire(1, 0, traceLca.size()); for(int iRequete = 0; iRequete < nbRequetes; iRequete++) { //lca dep arrivee + detection si empeche est un ancetre, comparaison des profondeurs int routeFerme, depart; cin >> routeFerme >> depart; --routeFerme; --depart; // cout << "deb" << endl; int interditDePasse = plusHaut(routeFerme).first, autre = plusHaut(routeFerme).second; bool surChemin = ((liaison(depart, interditDePasse) && (liaison(depart, autre)) && (profondeur[depart] > profondeur[interditDePasse])) || (liaison(destination, interditDePasse) && (liaison(destination, autre)) && (profondeur[destination] > profondeur[interditDePasse])));// // cout << "deb " << depart << " " << destination << " : " << routeFerme << endl; // cout << surChemin << " " << lca(depart, destination) << endl; if(surChemin && (profondeur[lca(depart, destination)] <= profondeur[interditDePasse])) { cout << 0 << "\n"; } else cout << "escaped" << "\n"; } // trouverPlusProche(0, -1); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...