Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.16 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <array>
  4. using namespace std;
  5.  
  6. int preorder[200000+5];
  7. int father[200000+5];
  8. pair<long long, int> seg_tree[550000];
  9. pair<int, int> przedz_seg_tree[550000];
  10. vector<int> sasiedzi[200000+5];
  11. vector<int> synowie[200000+5];
  12. int roz[200000+5];
  13. int uzyteczne[200000+5];
  14.  
  15. int n;
  16. int temp_preorder = 1;
  17. int max_pot = 1;
  18. long long numer_grupy=1;
  19.  
  20.  
  21. void make_Tree(int w)
  22. {
  23.     int ile_sas = sasiedzi[w].size();
  24.     for(int i=0; i<ile_sas; i++)
  25.     {
  26.         if(father[sasiedzi[w][i]] == 0)
  27.         {
  28.             father[sasiedzi[w][i]] = w;
  29.             synowie[w].push_back(sasiedzi[w][i]);
  30.             make_Tree(sasiedzi[w][i]);
  31.         }
  32.     }
  33. }
  34.  
  35. void make_Preorder(int w)
  36. {
  37.     preorder[w] = temp_preorder;
  38.     temp_preorder++;
  39.     int ile_synow = synowie[w].size();
  40.     for(int i=0; i<ile_synow; i++)
  41.         make_Preorder(synowie[w][i]);
  42.  
  43. }
  44.  
  45. void change_Add(int akt_poz, int pocz, int konc, int w_ojca, int i) ///NOWA WARTOSC JEST STALA DLA CALEGO PRZEDZIALU
  46. {
  47.  
  48.     ///1. JESLI PRZEDZIAL DLA WIERZCHOLKA CALKOWICIE SIE ZAWIERA
  49.    // cout<<"JESTEM W CHANGE ADD"<<endl;
  50.  
  51.     //cout<<"akt_poz: "<<akt_poz<<" POCZ: "<<pocz<<" KONC: "<<konc<<" przedz_seg_tree[akt_poz].first: " <<przedz_seg_tree[akt_poz].first<<" przedz_seg_tree[akt_poz].second: "<<przedz_seg_tree[akt_poz].second<<endl;
  52.     if(pocz <= przedz_seg_tree[akt_poz].first && konc >= przedz_seg_tree[akt_poz].second && i>=seg_tree[akt_poz].second)
  53.     {
  54.        // cout<<"PRZEDZIAL W PELNI SIE ZAWIERA W POSZUKIWANYM"<<endl;
  55.         seg_tree[akt_poz].first = w_ojca;
  56.         seg_tree[akt_poz].second = i;
  57.         return;
  58.     }
  59.  
  60.     ///2.JESLI W OGOLE NIE JEST ZAWARTE
  61.     else if(pocz > przedz_seg_tree[akt_poz].second || konc < przedz_seg_tree[akt_poz].first)
  62.         //{cout<<"WCALE"<<endl;
  63.         {return;}
  64.  
  65.     ///3.JEST ZAWARTE CZESCIOWO
  66.     else
  67.     {
  68.        // cout<<"CZESCIOWO"<<endl;
  69.         change_Add(akt_poz*2, pocz, konc, w_ojca, i);
  70.         change_Add(akt_poz*2+1, pocz, konc, w_ojca, i);
  71.     }
  72. }
  73.  
  74. void change_Divide(int akt_poz, int pocz, int konc, int i)
  75. {
  76.  
  77.     ///1. JESLI PRZEDZIAL DLA WIERZCHOLKA CALKOWICIE SIE ZAWIERA
  78.     if(pocz <= przedz_seg_tree[akt_poz].first && konc >= przedz_seg_tree[akt_poz].second && seg_tree[akt_poz].second < i)
  79.     {
  80.         seg_tree[akt_poz].first = numer_grupy;///!!!
  81.         seg_tree[akt_poz].second = i;
  82.         return;
  83.     }
  84.  
  85.     ///2.JESLI W OGOLE NIE JEST ZAWARTE
  86.     else if(pocz > przedz_seg_tree[akt_poz].second || konc < przedz_seg_tree[akt_poz].first)
  87.         return;
  88.  
  89.     ///3.JEST ZAWARTE CZESCIOWO
  90.     else
  91.     {
  92.         change_Divide(akt_poz*2, pocz, konc, i);
  93.         change_Divide(akt_poz*2+1, pocz, konc, i);
  94.     }
  95. }
  96.  
  97. int Find(int w)
  98. {
  99.     //cout<<"FIND dla: "<<w<<endl;
  100.     int ind = max_pot+w-1;
  101.     ///MA ZWRACAC GRUPE DO JAKIEJ NALEZY
  102.     //WARTOSCI POCZATKOWE:
  103.     long long fir = seg_tree[ind].first;  ///DOCELOWO GRUPA DLA NAJNIZSZEJ ZMIANY
  104.     int sec = seg_tree[ind].second; ///DOCELOWO NAJNIZSZA ZMIANA
  105.     do{
  106.         ind/=2;
  107.         if(seg_tree[ind].second > sec || fir == 0)
  108.         {sec = seg_tree[ind].second; fir = seg_tree[ind].first;}
  109.     }while(ind>1);
  110.  
  111.     return fir;
  112.  
  113.  
  114. }
  115.  
  116. void Add(int i)
  117. {
  118.     uzyteczne[i] = true; ///!!!
  119.  
  120.   //  cout<<"DODAJE DLA WIERZCHOLKA: "<<i<<endl;
  121.  
  122.     int wartosc_ojca = Find(preorder[father[i]]);
  123.     seg_tree[max_pot+preorder[i]-1].first = wartosc_ojca;
  124.     seg_tree[max_pot+preorder[i]-1].second = i;
  125.  
  126.     //cout<<"POCZ ZMIAN: "<<preorder[i]<<" KONIEC: "<<preorder[i] + roz[i] - 1<<endl;
  127.  
  128.     //change_Add(1, preorder[i],preorder[i] + roz[i] - 1,wartosc_ojca, i);
  129.     int ile_synow = synowie[i].size();
  130.     for(int j=0; j<ile_synow; j++)
  131.     {
  132.         change_Add(1, preorder[synowie[i][j]],preorder[synowie[i][j]] + roz[synowie[i][j]] - 1,wartosc_ojca, i);
  133.     }
  134. }
  135.  
  136. void Divide(int i)
  137. {
  138.     uzyteczne[i] = false; ///!!!
  139.     numer_grupy++;
  140.  
  141.     seg_tree[max_pot+preorder[i]-1].first = numer_grupy;
  142.     seg_tree[max_pot+preorder[i]-1].second = i;
  143.  
  144.     //cout<<"DZIELE DLA WIERZCHOLKA: "<<i<<endl;
  145.     int ile_synow = synowie[i].size();
  146.     for(int j=0; j<ile_synow; j++)
  147.     {
  148.         numer_grupy++;
  149.         //cout<<"POCZ ZMIAN: "<<preorder[synowie[i][j]]<<" KONIEC: "<<preorder[synowie[i][j]]+roz[synowie[i][j]]-1<<endl;
  150.         change_Divide(1, preorder[synowie[i][j]], preorder[synowie[i][j]]+roz[synowie[i][j]]-1, i);
  151.     }
  152. }
  153.  
  154. void Ans(int A, int B)
  155. {
  156.     if(Find(preorder[A]) == Find(preorder[B]) && uzyteczne[A] == true && uzyteczne[B] == true)
  157.         cout<<"TAK"<<endl;
  158.     else
  159.         cout<<"NIE"<<endl;
  160.  
  161.  
  162. }
  163.  
  164.  
  165. int make_Roz(int w)
  166. {
  167.     if(roz[w] != -1)
  168.         return roz[w];
  169.     else
  170.     {
  171.         if(synowie[w].empty())
  172.             {roz[w] = 1; return 1;}
  173.         else
  174.         {
  175.             int temp=1;
  176.             int ile_sas = synowie[w].size();
  177.             for(int i=0; i<ile_sas; i++)
  178.             {
  179.                 temp+=make_Roz(synowie[w][i]);
  180.             }
  181.  
  182.             roz[w] = temp;
  183.             return temp;
  184.         }
  185.     }
  186. }
  187.  
  188. int main()
  189. {
  190.     ios_base::sync_with_stdio(0);
  191.     cin.tie(0);
  192.  
  193.     cin>>n;
  194.  
  195.     int t1;
  196.     int t2;
  197.     for(int i=1; i<n; i++)
  198.     {
  199.         cin>>t1;
  200.         cin>>t2;
  201.         sasiedzi[t1].push_back(t2);
  202.         sasiedzi[t2].push_back(t1);
  203.     }
  204.  
  205.     ///STWORZENIE TABLICY OJCOW I SYNOW
  206.     father[1] = 1;
  207.     make_Tree(1);
  208.     /*cout<<"FATHER"<<endl;
  209.     for(int i=1; i<=n; i++)
  210.         cout<<i<<": "<<father[i]<<endl;*/
  211.  
  212.  
  213.     for(int i=1; i<=n; i++)
  214.         roz[i] = -1;
  215.  
  216.     make_Roz(1);
  217.     ///STWORZENIE TABLICY PREORDER
  218.     make_Preorder(1);
  219.     //cout<<endl;
  220.     //cout<<"PREORDER"<<endl;
  221.     //for(int i=1; i<=n; i++)
  222.       //  cout<<i<<": "<<preorder[i]<<endl;
  223.  
  224.     ///STWORZENIE DRZEWA PRZEDZIALOWEGO i obliczenie ZAKRESOW dla wierzcholkow
  225.     while(max_pot<n)
  226.         max_pot*=2;
  227.     //cout<<"max_pot: "<<max_pot<<endl;
  228.  
  229.     for(int i=max_pot; i<2*max_pot; i++)
  230.     {przedz_seg_tree[i].first = i-max_pot+1;
  231.      przedz_seg_tree[i].second = i-max_pot+1; }
  232.  
  233.     for(int i=max_pot-1; i>=1; i--)
  234.     {
  235.         przedz_seg_tree[i].first = przedz_seg_tree[2*i].first;
  236.         przedz_seg_tree[i].second = przedz_seg_tree[2*i+1].second;
  237.     }
  238.     /*cout<<endl;
  239.     cout<<"ZAKRESY"<<endl;
  240.     for(int i=1; i<2*max_pot; i++)
  241.         cout<<i<<": "<<przedz_seg_tree[i].first<<"   "<<przedz_seg_tree[i].second<<endl;
  242.  
  243.  
  244.     cout<<endl;
  245.     cout<<"ROZ"<<endl;
  246.     for(int i=1; i<2*max_pot; i++)
  247.         cout<<i<<": "<<roz[i]<<endl;*/
  248.     for(int i=0; i<=n; i++)
  249.         uzyteczne[i] = true;
  250.  
  251.  
  252.     int q;
  253.     cin>>q;
  254.     char ct1;
  255.     int tem2;
  256.     int t3;
  257.     for(int i=0; i<q; i++)
  258.     {
  259.         cin>>ct1;
  260.         cin>>tem2;
  261.         if(ct1 == '?')
  262.         {cin>>t3; Ans(tem2, t3);}
  263.         else if(ct1 == '+')
  264.             Add(tem2);
  265.         else
  266.             Divide(tem2);
  267.  
  268.         /*cout<<"DRZEWO PO ZMIANACH"<<endl;
  269.         for(int j=1; j<2*max_pot; j++)
  270.             cout<<j<<": "<<seg_tree[j].first<<"   "<<seg_tree[j].second<<endl;
  271.           cout<<endl;
  272.         for(int ind=1; ind<=n; ind++)
  273.             cout<<ind<<": "<<Find(ind)<<'\t';
  274.         cout<<endl;*/
  275.  
  276.     }
  277.  
  278.  
  279.  
  280.     return 0;
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement