Advertisement
Guest User

Untitled

a guest
Jan 25th, 2020
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.66 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4.  
  5. const int MAXN = 1e5 + 5;
  6.  
  7. using namespace std;
  8.  
  9. ifstream in("heavypath.in");
  10. ofstream out("heavypath.out");
  11.  
  12. /// nod_lant[i] = in ce lant se afla nodul i
  13. /// pozitie[i] = pe ce pozitie se afla in lantul (deja stiut) nodul i
  14. /// inaltime[i] = care este inaltimea lantului care se afla pe pozitia i
  15. /// daca am lantul pe ex : 4 3 2 1(e luat de la spate in fata din cauza la dfs)
  16. /// atunci nod_lant[4] = nod_lant[3] = nod_lant[2] = nod_lant[1] = 1 primul lant
  17. /// pozitie[4] = 1 in lant se alfa pe poz 1, pozitie[3] = 2, pozitie[2] = 3, pozitie[1] = 4
  18. /// inaltime[1] = 1, se afla la inaltimea 1, dar lantul 9 8 7 se afla la inaltimea 2
  19. /// daca citeste cineva asta sper sa inteleaga :)
  20. /// singurul vector indexat de la 0 este lant[i]
  21.  
  22. int tata[MAXN],dimensiune[MAXN],nod_lant[MAXN],pozitie[MAXN],inaltime[MAXN];
  23. int valori[MAXN];
  24.  
  25.  
  26. bool viz[MAXN];
  27. int nr_lanturi;
  28. vector<int>arbore_intervale[MAXN];/// Sunt indexati de la 1!!!!!
  29.  
  30.  
  31. vector<int>lant[MAXN];/// indexati de la 0!!
  32. vector<int>graf[MAXN];
  33.  
  34. void dfs(int nod,int anterior = -1){
  35. dimensiune[nod] = 1;
  36. viz[nod] = true;
  37. int curent;
  38. for(int i = 0; i < graf[nod].size(); i++){
  39. curent = graf[nod][i];
  40. if(curent == anterior){
  41. /// anteriorul este nodul care a fost parcurs inainte
  42. /// daca eu vreau sa ma duc cu o muchie in spate atunci tatal nodului curent este anterior
  43. tata[nod] = anterior;
  44. }
  45. if(!viz[curent]){
  46. dfs(curent,nod);
  47. dimensiune[nod] += dimensiune[curent];
  48. }
  49.  
  50. }
  51.  
  52. if(graf[nod].size() == 1 && nod != 1){
  53. lant[++nr_lanturi].push_back(nod);
  54. nod_lant[nod] = nr_lanturi;
  55. pozitie[nod] = 1; /// il pun pe pozitia 1
  56. }else{
  57. int vecin_bun,maxim = 0;
  58. for(int i = 0; i < graf[nod].size(); i++){
  59. int curent = graf[nod][i];
  60. if(dimensiune[curent] > maxim && curent != anterior){
  61. vecin_bun = curent;
  62. maxim = dimensiune[curent];
  63. }
  64. }
  65. int unde = nod_lant[vecin_bun];
  66. lant[unde].push_back(nod); /// adaug nodul nod la lantul cu subarborele maxim
  67. nod_lant[nod] = unde;
  68. pozitie[nod] = lant[unde].size();/// il pun pe ultima pozitie
  69.  
  70. for(int i = 0; i < graf[nod].size(); i++){
  71. int curent = graf[nod][i];
  72. if(nod_lant[curent] != nod_lant[nod])
  73. ///Vlad: Modifici inaltimea lantului unui fiu fara sa ai calculata inaltimea lantului nodului
  74. inaltime[nod_lant[curent]] = inaltime[nod_lant[nod]] + 1; /// modific inaltimea lantului
  75. }
  76. }
  77. }
  78. void update(int index_lant,int val,int pozitie,int st,int dr,int nod = 1){
  79. ///cout<<st<<" "<<dr<<" "<<pozitie<<" "<<nod<<endl;
  80. if(st == dr && st == pozitie){
  81. arbore_intervale[index_lant][nod] = val;
  82. return;
  83. }
  84. int mij = (st + dr) / 2;
  85. if(pozitie <= mij)
  86. update(index_lant,val,pozitie,st,mij,nod * 2);
  87. else
  88. update(index_lant,val,pozitie,mij + 1,dr,nod * 2 + 1);
  89. if(nod * 2 + 1 < arbore_intervale[index_lant].size()) /// sa nu cumva sa ies din size
  90. arbore_intervale[index_lant][nod] = max(arbore_intervale[index_lant][nod * 2],arbore_intervale[index_lant][nod * 2 + 1]);
  91. }
  92. int query(int index_lant,int query_left,int query_right,int st,int dr,int nod = 1){
  93. ///cout<<st<<" "<<dr<<" "<<nod<<" "<<arbore_intervale[index_lant][nod]<<endl;
  94. if(query_left <= st && dr <= query_right)
  95. return arbore_intervale[index_lant][nod];
  96. int mij = (st + dr) / 2;
  97. int val_stanga = 0,val_dreapta = 0;
  98. if(query_left <= mij)
  99. val_stanga = query(index_lant,query_left,query_right,st,mij,nod * 2);
  100. if(mij + 1 <= query_right)
  101. val_dreapta = query(index_lant,query_left,query_right,mij + 1,dr,nod * 2 + 1);
  102.  
  103. return max(val_stanga,val_dreapta);
  104. }
  105. int query_lant(int nod){
  106. int index_lant = nod_lant[nod];
  107. int dimensiune = lant[index_lant].size();
  108. int poz = pozitie[nod];/// pozitie e de la 1 indexat
  109. return query(index_lant,poz,dimensiune,1,dimensiune);
  110. }
  111. int intrebare(int a,int b){
  112. /// calculez usor usor lca intre a si b
  113. if(inaltime[nod_lant[a]] < inaltime[nod_lant[b]])
  114. swap(a,b);
  115. /// a este intr-un lant mai sus decat b
  116. int maxim = max(query_lant(a),query_lant(b)); ///Vlad: nu garanteaza nimic ca a este intr-un lant mai sus decat b. pot fi foarte bine pe acelasi lant.
  117. while(inaltime[nod_lant[a]] > inaltime[nod_lant[b]]){
  118. int urmatorul = lant[nod_lant[a]].back();/// ultimul element
  119. a = tata[urmatorul];
  120. maxim = max(maxim,query_lant(a));
  121. }
  122. /// sunt pe aceasi inaltime
  123. while(nod_lant[a] != nod_lant[b]){
  124. int urmatorul = lant[nod_lant[a]].back();
  125. a = tata[urmatorul];
  126. maxim = max(maxim,query_lant(a));
  127. urmatorul = lant[nod_lant[b]].back();
  128. b = tata[urmatorul];
  129. maxim = max(maxim,query_lant(b));
  130. }
  131.  
  132. /// sunt in acelasi lant
  133. /// eu vreau ca a sa fie mai jos pe lant
  134. /// vectorul de pozitii este pe invers adica pt lantul 4 3 2 1, poz : 1 2 3 4
  135. /// vreau ca poz[a] < poz[b] daca nu, fac este swap(a,b)
  136. ///cout<<a<<" "<<b<<" "<<" pozitii : "<<pozitie[a]<<" "<<pozitie[b]<<endl;
  137. if(pozitie[a] > pozitie[b])
  138. swap(a,b);
  139. int query_pe_lant = query(nod_lant[a],pozitie[a],pozitie[b],1,lant[nod_lant[a]].size());
  140. maxim = max(maxim,query_pe_lant);
  141. /// acum stiu clar ca a = b;
  142. out<<maxim<<"\n";
  143. }
  144.  
  145. void construieste_arbore(int index_lant){
  146. vector<int>arbore(4 * lant[index_lant].size() + 2);
  147.  
  148. arbore_intervale[index_lant] = arbore;
  149. int lung_lant = lant[index_lant].size();
  150. for(int i = 0; i < lant[index_lant].size(); i++){
  151. int val = valori[lant[index_lant][i]];
  152. update(index_lant,val,i + 1,1,lung_lant);/// !! indexati de la 1 de aia poz = i + 1
  153. }
  154. }
  155.  
  156.  
  157.  
  158. int main()
  159. {
  160. int n,intrebari;
  161. in>>n>>intrebari;
  162. for(int i = 1; i <= n; i++)
  163. in>>valori[i];
  164. for(int i = 1; i <= n - 1; i++){
  165. int x,y;
  166. in>>x>>y;
  167. graf[x].push_back(y);
  168. graf[y].push_back(x);
  169. }
  170. inaltime[1] = 1;
  171. dfs(1);
  172. for(int i = 1; i <= n; i++)
  173. construieste_arbore(i);
  174. for(int i = 1; i <= intrebari; i++){
  175. int cerinta,a,b;
  176. in>>cerinta>>a>>b;
  177. if(cerinta == 1){
  178. intrebare(a,b);
  179. }else{
  180. int index_lant = nod_lant[a];
  181. int pozitie_lant = pozitie[a];
  182. update(index_lant,b,pozitie_lant,1,lant[index_lant].size());
  183. }
  184. }
  185. return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement