Advertisement
Guest User

Untitled

a guest
Aug 21st, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.48 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <climits>
  4. #include <set>
  5. using namespace std;
  6.  
  7. vector <int> sas [100005];
  8. vector <int> synowie[100005];
  9. bool odw[100005];
  10. int father[100005];
  11. int nim_baz[100005];
  12. int spr_mexow[100005];
  13. int spr_mexow2[100005];
  14. int spr_mexow3[100005];
  15. int nim[100005];
  16. int temp_nim[100005];
  17. int ost_nim[100005];
  18. int mexy_drzew[100005];
  19. set <int> unikalne_wart_synow[100005];
  20.  
  21. int prefix_xor[100005];
  22. int sufiks_xor[100005];
  23.  
  24.  
  25. int global_n = 0;
  26. int wyw_make_temp = 0;
  27.  
  28. void zeruj_odw()
  29. {
  30.     for(int i=1; i<=global_n; i++)
  31.         odw[i] = 0;
  32. }
  33.  
  34. void DFS_make_tree(int i)
  35. {
  36.     odw[i] = 1;
  37.  
  38.     int ile_sas = sas[i].size();
  39.     for(int j=0; j<ile_sas; j++)
  40.         if(!odw[sas[i][j]])
  41.         {
  42.             father[sas[i][j]] = i;
  43.             synowie[i].push_back(sas[i][j]);
  44.             DFS_make_tree(sas[i][j]);
  45.         }
  46. }
  47.  
  48. void DFS_nim_baz(int i)
  49. {
  50.     odw[i] = 1;
  51.  
  52.     int ile_synow = synowie[i].size();
  53.  
  54.     if(ile_synow==0)
  55.     {
  56.         nim_baz[i] = 0; ///POZYCJA PRZEGRYWAJACA
  57.         return;
  58.     }
  59.  
  60.     else
  61.     {
  62.         for(int j=0; j<ile_synow; j++)
  63.             DFS_nim_baz(synowie[i][j]);
  64.  
  65.         nim_baz[i] = 0;
  66.  
  67.         ///DLA KAZDEGO SYNA
  68.         for(int j=0; j<ile_synow; j++)
  69.         {
  70.             ///ZAZNACZAM W TABLICY SPR_MEXOW INDEKS I
  71.             if(spr_mexow[nim_baz[synowie[i][j]]] == i)
  72.                 spr_mexow[nim_baz[synowie[i][j]]] = i+1000000;
  73.  
  74.             else if(spr_mexow[nim_baz[synowie[i][j]]] != i+1000000)
  75.                 spr_mexow[nim_baz[synowie[i][j]]] = i;
  76.         }
  77.  
  78.       /*  if(father[i] != i)
  79.         {
  80.             if(spr_mexow[nim_baz[father[i]]] == i)
  81.                 spr_mexow[nim_baz[father[i]]] = i+1000000;
  82.  
  83.             else if(spr_mexow[nim_baz[father[i]]] != i+1000000)
  84.                 spr_mexow[nim_baz[nim_baz[father[i]]]] = i;
  85.  
  86.         }*/
  87.  
  88.         for(int j=0; j<=100000; j++)
  89.         {
  90.             if(spr_mexow[j] == i)
  91.                 {//cout<<"DODANIE UNIKALNEJ WARTOSCI: "<<j<<"dla: "<<i<<endl;
  92.                 unikalne_wart_synow[i].insert(j);}
  93.             if(spr_mexow[j] != i && spr_mexow[j] != i+1000000)
  94.                 {nim_baz[i] = j;  return; }
  95.         }
  96.     }
  97. }
  98.  
  99. void make_temp(int ja, int nieleg_syn)
  100. {
  101.    int nim_syna = temp_nim[nieleg_syn];
  102.    int nim_ojca = temp_nim[ja];
  103.  
  104.    ///JEZLI NIM SYNA JEST 1) MNIEJSZY OD NIM OJCA, 2) JEST UNIKALNY, TO NOWY NIM OJCA = NIM SYNA
  105.    if(unikalne_wart_synow[ja].count(nim_syna) && (father[ja] == ja || temp_nim[father[ja]] != nim_syna))
  106.         temp_nim[ja] = nim_syna;
  107. }
  108.  
  109. void DFS_nim(int i)
  110. {
  111.    // cout<<"WYWOLANO DSF_NIM: "<<i<<endl;
  112.  
  113.     odw[i] = 1;
  114.     int ile_synow = synowie[i].size();
  115.  
  116.     if(father[i]==i)
  117.         ost_nim[i] = nim_baz[i];
  118.  
  119.     else
  120.     {
  121.     ///na bazie temp_nim ojca i synow tworze wlasny ost_nim
  122.  
  123.         ///JA JESTEM NOWYM KORZENIEM czyt. zmienia sie orien. miedzy ojcem a mna
  124.         ///musze policzyc nowy temp dla ojca
  125.         make_temp(father[i], i);
  126.         spr_mexow2[temp_nim[father[i]]] = i;
  127.  
  128.         for(int j=0; j<ile_synow; j++)
  129.             spr_mexow2[temp_nim[synowie[i][j]]] = i;
  130.  
  131.         for(int j=0; j<=100000; j++)
  132.             if(spr_mexow2[j] != i)
  133.                 {ost_nim[i] = j; j=100000+5;}
  134.  
  135.     }
  136.  
  137.  
  138.     for(int j=0; j<ile_synow; j++)
  139.         DFS_nim(synowie[i][j]);
  140.  
  141.     temp_nim[i] = nim_baz[i];
  142.     //temp_nim[father[i]] = nim_baz[father[i]];
  143.  
  144.  //   cout<<"WYCHODZE Z DFS_NIM: "<<i<<"WYNIK OST: "<<ost_nim[i]<<endl;
  145.    // cout<<endl;
  146.     }
  147.  
  148. void DFS_mex(int i, int gdzie_mex)
  149. {
  150.     odw[i] = 1;
  151.     int ile_synow = synowie[i].size();
  152.     for(int j=0; j<ile_synow; j++)
  153.     {
  154.         spr_mexow3[ost_nim[synowie[i][j]]] = gdzie_mex;
  155.         DFS_mex(synowie[i][j], gdzie_mex);
  156.     }
  157. }
  158.  
  159.  
  160. int make_mexy_drzew(int i)
  161. {
  162.  
  163.     mexy_drzew[i] = ost_nim[i];
  164.     spr_mexow3[ost_nim[i]] = i;
  165.     ///PUSZCZAM DFS PO DRZEWIE I XOROJE MEXY DRZEW I
  166.     DFS_mex(i, i);
  167.  
  168.  
  169.    for(int j=0; j<=100000; j++)
  170.             if(spr_mexow3[j] != i)
  171.                 {mexy_drzew[i] = j; j=100000+5;}
  172.     return mexy_drzew[i];
  173.  
  174. }
  175.  
  176.  
  177.  
  178.  
  179. int main()
  180. {
  181.     ios_base::sync_with_stdio(0);
  182.     cin.tie(0);
  183.  
  184.     int k;
  185.     int n;
  186.  
  187.     cin>>k;
  188.  
  189.     int a;
  190.     int b;
  191.     for(int i=1; i<=k; i++)
  192.     {
  193.         cin>>n;
  194.         for(int j=1; j<=n-1; j++)
  195.         {
  196.             cin>>a;
  197.             cin>>b;
  198.  
  199.             sas[global_n+a].push_back(global_n+b);
  200.             sas[global_n+b].push_back(global_n+a);
  201.         }
  202.         global_n+=n;
  203.     }
  204.  //   cout<<global_n<<endl;
  205.  
  206.     ///STWORZ DRZEWA
  207.     for(int i=1; i<=global_n; i++)
  208.         if(!odw[i])
  209.         {
  210.             father[i] = i;
  211.             DFS_make_tree(i);
  212.  
  213.         }
  214.  
  215.   //  for(int i=1; i<=global_n; i++)
  216.     //    cout<<"i: "<<i<<" father: "<<father[i]<<endl;
  217.  
  218.     zeruj_odw();
  219.  
  220.     for(int i=1; i<=global_n; i++)
  221.         if(!odw[i])
  222.             DFS_nim_baz(i);
  223.  
  224.  
  225.  
  226. //    for(int i=1; i<=global_n; i++)
  227.   //      cout<<"i: "<<i<<" nim_baz: "<<nim_baz[i]<<endl;
  228.  
  229. //    cout<<endl;
  230.   //  cout<<endl;
  231.     ///DOTAD OK
  232.  
  233.     zeruj_odw();
  234.     for(int i=0; i<=100005; i++)
  235.         spr_mexow[i] = 0;
  236.  
  237.  
  238.      for(int i=1; i<=global_n; i++)
  239.         temp_nim[i] = nim_baz[i];
  240.  
  241.  
  242.     for(int i=1; i<=global_n; i++)
  243.         if(!odw[i])
  244.             DFS_nim(i);
  245.  
  246. //for(int i=1; i<=global_n; i++)
  247.   //     cout<<"i: "<<i<<" ost_nim: "<<ost_nim[i]<<endl;
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.    // return 0;
  268.     ///DOTAD OK, KORZYSTAMY TERAZ TYLKO Z OST_NIM JAKO ZBIORU NIM SUM
  269.  
  270.     /// DLA KAZDEGO WIERZCHOLKA KTORY JEST KORZENIEM W TABLICY "MEXY" DAJEMY MEXA Z DRZEWA
  271.     ///DLA WIERZCHOLKOW NIE-KORZENI ZAPISUJE 0 - NIE ZMIENI TO WYNIKU XORA
  272.  
  273.     zeruj_odw();
  274.  
  275.     vector<pair<int, int>> mexy; ///mexy kolejnych drzew i numery ich korzeni
  276.  
  277.  
  278.     for(int i=1; i<=global_n; i++)
  279.         if(!odw[i])
  280.             mexy.push_back(make_pair(make_mexy_drzew(i), i));
  281.  
  282.  
  283.     int xor_ = 0;
  284.     for(int i=0; i<mexy.size(); i++)
  285.         xor_ = xor_ ^ mexy[i].first;
  286.  
  287.     if(xor_ == 0)
  288.     {cout<<0; return 0;}
  289.  
  290.  
  291.     int result = 0;
  292.     mexy.push_back(make_pair(0,global_n+1)); ///potrzebne by poznac koniec realnie ostatinego drzewa
  293.     ///DLA KAZDEGO DRZEWA
  294.     for(int i=0; i<mexy.size()-1; i++)
  295.     {
  296.         xor_ = xor_ ^ mexy[i].first;
  297.         for(int j=mexy[i].second; j<mexy[i+1].second; j++)
  298.         {
  299.             if(!(xor_ ^ ost_nim[j]))
  300.                 result++;
  301.         }
  302.         xor_ = xor_ ^ mexy[i].first;
  303.     }
  304.  
  305.     cout<<result;
  306.  
  307.  
  308.  
  309.  
  310.     return 0;
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement