Advertisement
Guest User

Untitled

a guest
Aug 22nd, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.61 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.     bool t=0;
  88.         for(int j=0; j<=500; 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 && t==0)
  94.                 {nim_baz[i] = j;  t=1;//return;
  95.                 }
  96.         }
  97.     }
  98. }
  99.  
  100. void make_temp(int ja, int nieleg_syn)
  101. {
  102.    int nim_syna = temp_nim[nieleg_syn];
  103.    int nim_ojca = temp_nim[ja];
  104.  
  105.    ///JEZLI NIM SYNA JEST 1) MNIEJSZY OD NIM OJCA, 2) JEST UNIKALNY, TO NOWY NIM OJCA = NIM SYNA
  106.    if(unikalne_wart_synow[ja].count(nim_syna) && nim_syna<=nim_ojca &&(father[ja] == ja || temp_nim[father[ja]] != nim_syna))
  107.         temp_nim[ja] = nim_syna;
  108.  
  109.     else
  110.         temp_nim[ja] = ost_nim[ja];
  111. }
  112.  
  113. void DFS_nim(int i)
  114. {
  115.     //cout<<"WYWOLANO DSF_NIM: "<<i<<endl;
  116.  
  117.     odw[i] = 1;
  118.     int ile_synow = synowie[i].size();
  119.  
  120.     if(father[i]==i)
  121.         ost_nim[i] = nim_baz[i];
  122.  
  123.     else
  124.     {
  125.     ///na bazie temp_nim ojca i synow tworze wlasny ost_nim
  126.  
  127.         ///JA JESTEM NOWYM KORZENIEM czyt. zmienia sie orien. miedzy ojcem a mna
  128.         ///musze policzyc nowy temp dla ojca
  129.         make_temp(father[i], i);
  130.         spr_mexow2[temp_nim[father[i]]] = i;
  131.  
  132.         for(int j=0; j<ile_synow; j++)
  133.             spr_mexow2[temp_nim[synowie[i][j]]] = i;
  134.  
  135.         for(int j=0; j<=100000; j++)
  136.             if(spr_mexow2[j] != i)
  137.                 {ost_nim[i] = j; j=100000+5;}
  138.  
  139.     }
  140.  
  141.  
  142.     for(int j=0; j<ile_synow; j++)
  143.         DFS_nim(synowie[i][j]);
  144.  
  145.     temp_nim[i] = nim_baz[i];
  146.  //   temp_nim[father[i]] = nim_baz[father[i]];
  147.  
  148.   //  cout<<"WYCHODZE Z DFS_NIM: "<<i<<"WYNIK OST: "<<ost_nim[i]<<endl;
  149.    // cout<<endl;
  150.     }
  151.  
  152. void DFS_mex(int i, int gdzie_mex)
  153. {
  154.     odw[i] = 1;
  155.     int ile_synow = synowie[i].size();
  156.     for(int j=0; j<ile_synow; j++)
  157.     {
  158.         spr_mexow3[ost_nim[synowie[i][j]]] = gdzie_mex;
  159.         DFS_mex(synowie[i][j], gdzie_mex);
  160.     }
  161. }
  162.  
  163.  
  164. int make_mexy_drzew(int i)
  165. {
  166.  
  167.     mexy_drzew[i] = ost_nim[i];
  168.     spr_mexow3[ost_nim[i]] = i;
  169.     ///PUSZCZAM DFS PO DRZEWIE I XOROJE MEXY DRZEW I
  170.     DFS_mex(i, i);
  171.  
  172.  
  173.    for(int j=0; j<=100000; j++)
  174.             if(spr_mexow3[j] != i)
  175.                 {mexy_drzew[i] = j; j=100000+5;}
  176.     return mexy_drzew[i];
  177.  
  178. }
  179.  
  180.  
  181.  
  182.  
  183. int main()
  184. {
  185.     ios_base::sync_with_stdio(0);
  186.     cin.tie(0);
  187.  
  188.     int k;
  189.     int n;
  190.  
  191.     cin>>k;
  192.  
  193.     int a;
  194.     int b;
  195.     for(int i=1; i<=k; i++)
  196.     {
  197.         cin>>n;
  198.         for(int j=1; j<=n-1; j++)
  199.         {
  200.             cin>>a;
  201.             cin>>b;
  202.  
  203.             sas[global_n+a].push_back(global_n+b);
  204.             sas[global_n+b].push_back(global_n+a);
  205.         }
  206.         global_n+=n;
  207.     }
  208.  //   cout<<global_n<<endl;
  209.  
  210.     ///STWORZ DRZEWA
  211.     for(int i=1; i<=global_n; i++)
  212.         if(!odw[i])
  213.         {
  214.             father[i] = i;
  215.             DFS_make_tree(i);
  216.  
  217.         }
  218.  
  219.     //for(int i=1; i<=global_n; i++)
  220.       //  cout<<"i: "<<i<<" father: "<<father[i]<<endl;
  221.  
  222.     zeruj_odw();
  223.  
  224.     for(int i=1; i<=global_n; i++)
  225.         if(!odw[i])
  226.             DFS_nim_baz(i);
  227.  
  228.  
  229.  
  230.  //  for(int i=1; i<=global_n; i++)
  231.    //     cout<<"i: "<<i<<" nim_baz: "<<nim_baz[i]<<endl;
  232.  
  233. //    cout<<endl;
  234.   //  cout<<endl;
  235.     ///DOTAD OK
  236.  
  237.     zeruj_odw();
  238.     for(int i=0; i<=100005; i++)
  239.         spr_mexow[i] = 0;
  240.  
  241.  
  242.      for(int i=1; i<=global_n; i++)
  243.         temp_nim[i] = nim_baz[i];
  244.  
  245.  
  246.     for(int i=1; i<=global_n; i++)
  247.         if(!odw[i])
  248.             DFS_nim(i);
  249.  
  250.    //         cout<<endl;
  251. //for(int i=1; i<=global_n; i++)
  252.   //     cout<<"i: "<<i<<" ost_nim: "<<ost_nim[i]<<endl;
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.    // return 0;
  273.     ///DOTAD OK, KORZYSTAMY TERAZ TYLKO Z OST_NIM JAKO ZBIORU NIM SUM
  274.  
  275.     /// DLA KAZDEGO WIERZCHOLKA KTORY JEST KORZENIEM W TABLICY "MEXY" DAJEMY MEXA Z DRZEWA
  276.     ///DLA WIERZCHOLKOW NIE-KORZENI ZAPISUJE 0 - NIE ZMIENI TO WYNIKU XORA
  277.  
  278.     zeruj_odw();
  279.  
  280.     vector<pair<int, int>> mexy; ///mexy kolejnych drzew i numery ich korzeni
  281.  
  282.  
  283.     for(int i=1; i<=global_n; i++)
  284.         if(!odw[i])
  285.             mexy.push_back(make_pair(make_mexy_drzew(i), i));
  286.  
  287.  
  288.     int xor_ = 0;
  289.     for(int i=0; i<mexy.size(); i++)
  290.         xor_ = xor_ ^ mexy[i].first;
  291.  
  292.     if(xor_ == 0)
  293.     {cout<<0; return 0;}
  294.  
  295.  
  296.     int result = 0;
  297.     mexy.push_back(make_pair(0,global_n+1)); ///potrzebne by poznac koniec realnie ostatinego drzewa
  298.     ///DLA KAZDEGO DRZEWA
  299.     for(int i=0; i<mexy.size()-1; i++)
  300.     {
  301.         xor_ = xor_ ^ mexy[i].first;
  302.         for(int j=mexy[i].second; j<mexy[i+1].second; j++)
  303.         {
  304.             if(!(xor_ ^ ost_nim[j]))
  305.                 result++;
  306.         }
  307.         xor_ = xor_ ^ mexy[i].first;
  308.     }
  309.  
  310.     cout<<result;
  311.  
  312.  
  313.  
  314.  
  315.     return 0;
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement