Submission #198438

#TimeUsernameProblemLanguageResultExecution timeMemory
198438model_codeAirplanes (LMIO17_lektuvai)C++17
100 / 100
197 ms26408 KiB
#include <algorithm> #include <cassert> #include <iostream> #include <cassert> #include <vector> #define endl '\n' using namespace std; struct Virsune { int pirmine_pozicija; pair<int, int> atsakinga; vector<int> vaikai; }; int N, S; vector<Virsune> priklausomybiu_medis; vector<int> segmentuotas_medis; void rasti_atsakingumo_rezius(int virsune, int &atsakingumo_pradzia) { Virsune &v = priklausomybiu_medis[virsune]; v.atsakinga.first = atsakingumo_pradzia; atsakingumo_pradzia += 1; for (int vaikas: v.vaikai) { rasti_atsakingumo_rezius(vaikas, atsakingumo_pradzia); } v.atsakinga.second = atsakingumo_pradzia - 1; #ifndef EVAL cerr << "Virsune " << virsune << " su pozicija " << v.pirmine_pozicija << " atsakinga uz [" << v.atsakinga.first << "; " << v.atsakinga.second << "]" << endl; #endif } void rasti_atsakingumo_rezius(int virsune) { int atsakingumo_pradzia = 1; rasti_atsakingumo_rezius(virsune, atsakingumo_pradzia); } int saugi_segmentuoto_medzio_reiksme(int pozicija) { return pozicija < S ? segmentuotas_medis[pozicija] : 0; } void keisti_segmentuotame_medyje(int pozicija, int nauja_reiksme) { int indeksas = (S + 1) / 2 + pozicija - 1; assert(segmentuotas_medis[indeksas] <= nauja_reiksme); segmentuotas_medis[indeksas] = nauja_reiksme; for (indeksas = indeksas / 2 /* pradedam nuo indekso tevinės viršūnės */; indeksas /* kol tėvinė viršūnė egzistuoja */; indeksas = indeksas / 2 /* lipam į kitą tėvinę viršūnę */) { // Viršūnės reikšmė -- maksimumas tarp vaikinių viršūnių. segmentuotas_medis[indeksas] = max( saugi_segmentuoto_medzio_reiksme(indeksas * 2), saugi_segmentuoto_medzio_reiksme(indeksas * 2 + 1)); } } int rasti_maksimuma_tarp(int virsune, int virsune_pradzia, int virsune_pabaiga, int intervalo_pradzia, int intervalo_pabaiga) { // Višūnė pilnai atsakinga už intervalo dalį. if (intervalo_pradzia <= virsune_pradzia && virsune_pabaiga <= intervalo_pabaiga) { return segmentuotas_medis[virsune]; } // Viršūnė yra neatsakinga už intervalo reikšmes. if (intervalo_pabaiga <= virsune_pradzia || virsune_pabaiga <= intervalo_pradzia) { return 0; } // Viršūnė atsakinga už dalį reikšmių. const int virsune_intervalo_ilgis = virsune_pabaiga - virsune_pradzia + 1; return max( // Kairiojo vaiko reikšmė. rasti_maksimuma_tarp(virsune * 2, virsune_pradzia, virsune_pradzia + virsune_intervalo_ilgis / 2, intervalo_pradzia, intervalo_pabaiga), // Dešiniojo vaiko reikšmė. rasti_maksimuma_tarp(virsune * 2 + 1, virsune_pradzia + virsune_intervalo_ilgis / 2, virsune_pabaiga, intervalo_pradzia, intervalo_pabaiga) ); } int rasti_maksimuma_tarp(const pair<int, int> &intervalas) { return rasti_maksimuma_tarp(1, 1, S / 2 + 1, intervalas.first, intervalas.second + 1); } void atspausdinti_segmentuota_medi() { for (int i : segmentuotas_medis) { cerr << " " << i; } cerr << endl; } void atspausdinti_pozicijas() { cerr << "{"; for (int i = 1; i <= N; i += 1) { cerr << (i == 1 ? "" : ", ") << i << ": " << rasti_maksimuma_tarp(priklausomybiu_medis[i].atsakinga); } cerr << "}" << endl; } int main() { ios_base::sync_with_stdio(false), cin.tie(0); cin >> N; priklausomybiu_medis.resize(N + 1); for (int i = 1; i <= N; i += 1) { cin >> priklausomybiu_medis[i].pirmine_pozicija; } for (int i = 1; i <= N - 1; i += 1) { int turi_buti_pries; cin >> turi_buti_pries; priklausomybiu_medis[turi_buti_pries].vaikai.push_back(i); } rasti_atsakingumo_rezius(N); for (S = 1; S < N; S *= 2); S = 2 * S; segmentuotas_medis.resize(S); for (int i = 1; i <= N; i += 1) { keisti_segmentuotame_medyje( priklausomybiu_medis[i].atsakinga.first, priklausomybiu_medis[i].pirmine_pozicija); } #ifndef EVAL cerr << "Segmentuotame medyje po jo inicilizavimo:"; atspausdinti_segmentuota_medi(); cerr << "Pozicijos: "; atspausdinti_pozicijas(); #endif int uzklausos; cin >> uzklausos; while (uzklausos--) { string uzklausa; int lektuvas; cin >> uzklausa >> lektuvas; const int lektuvo_pozicija = rasti_maksimuma_tarp(priklausomybiu_medis[lektuvas].atsakinga); if (uzklausa == "I") { cout << lektuvo_pozicija << endl; } else if (uzklausa == "P") { int pastumpti; cin >> pastumpti; keisti_segmentuotame_medyje( priklausomybiu_medis[lektuvas].atsakinga.first, lektuvo_pozicija + pastumpti); #ifndef EVAL cerr << "Segmentuotame medyje po pakeitimo:"; atspausdinti_segmentuota_medi(); cerr << "Visos pozicijos po pakeitimo: "; atspausdinti_pozicijas(); #endif } } 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...