Advertisement
willy108

spoj cot3

Apr 15th, 2022
1,173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.17 KB | None | 0 0
  1.  
  2. //misaka will carry me to master
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <cmath>
  7. #include <utility>
  8. #include <cassert>
  9. #include <algorithm>
  10. #include <vector>
  11. #include <functional>
  12. #include <numeric>
  13. #include <set>
  14. #include <map>
  15.  
  16. #define ll long long
  17. #define lb long double
  18. #define sz(vec) ((int)(vec.size()))
  19. #define all(x) x.begin(), x.end()
  20. #define pb push_back
  21. #define mp make_pair
  22.  
  23. const lb eps = 1e-9;
  24. const ll mod = 1e9 + 7, ll_max = 1e18;
  25. //const ll mod = (1 << (23)) * 119 +1;
  26. const int MX = 2e5 +10, int_max = 0x3f3f3f3f;
  27.  
  28. using namespace std;
  29.  
  30. //negative trust
  31. //so i need a trie that does
  32. //xor all and max
  33. //easiest is a push/pull implicit segtree
  34.  
  35. const int NN = MX*20;
  36.  
  37. char flag[NN];
  38. int lc[NN], rc[NN], tag[NN];
  39. int root[MX];
  40. int xum[MX], grundy[MX];
  41. int color[MX];
  42. vector<int> adj[MX];
  43.  
  44. int n;
  45. const int LG = 20, s = (1 << LG);
  46.  
  47. #define lsb(x) (x&(-x))
  48.  
  49. void push(int k, int a){
  50.     if(tag[k]){
  51.         if(a&tag[k]) swap(lc[k], rc[k]);
  52.         if(lc[k]) tag[lc[k]] ^= tag[k];
  53.         if(rc[k]) tag[rc[k]] ^= tag[k];
  54.     }
  55.     tag[k] = 0;
  56. }
  57.  
  58. void pull(int k){
  59.     if(flag[lc[k]] && flag[rc[k]]){
  60.         flag[k] = 1;
  61.     }
  62. }
  63.  
  64. void dup(int& k){
  65.     static int ind = 0;
  66.     if(!k)
  67.         k = ++ind;
  68. }
  69.  
  70. void U(int p, int &k, int L, int R){
  71.     dup(k);
  72.     if(L + 1 == R){
  73.         assert(L == p);
  74.         //cout << "wave\n";
  75.         flag[k] = 1;
  76.         return ;
  77.     }
  78.    
  79.     int mid = (L + R)/2;
  80.     push(k, lsb(mid));
  81.  
  82.     if(p < mid) U(p, lc[k], L, mid);
  83.     else U(p, rc[k], mid, R);
  84.     pull(k);
  85. }
  86.  
  87. void merge(int& k1, int k2, int d){
  88.     if(min(k1, k2) == 0){
  89.         k1 ^= k2;
  90.         return ;
  91.     }
  92.     if(d == 0){
  93.         return ;
  94.     }
  95.     push(k1, (1 << (d-1))); push(k2, (1 << (d-1)));
  96.     merge(lc[k1], lc[k2], d-1);
  97.     merge(rc[k1], rc[k2], d-1);
  98.     pull(k1);
  99. }
  100.  
  101. int mex(int k, int L, int R){
  102.     if(L + 1 == R) return L;
  103.     int mid = (L + R)/2;
  104.     push(k, lsb(mid));
  105.     if(flag[lc[k]]) return mex(rc[k], mid, R);
  106.     else return mex(lc[k], L, mid);
  107. }
  108.  
  109.  
  110.  
  111. void dfs(int u, int p){
  112.     for(int v : adj[u]){
  113.         if(v == p) continue;
  114.         dfs(v, u);
  115.         xum[u] ^= grundy[v];
  116.     }
  117.     if(color[u] == 0){
  118.         U(xum[u], root[u], 0, s);
  119.     }else{
  120.         dup(root[u]);
  121.     }
  122.     for(int v : adj[u]){
  123.         if(v == p) continue;
  124.         if(root[v]){
  125.             tag[root[v]] ^= xum[u] ^ grundy[v];
  126.             merge(root[u], root[v], LG); //i hope
  127.             //cout << "new root " << root[u] << "\n";
  128.         }
  129.     }
  130.     grundy[u] = mex(root[u], 0, s);
  131. }
  132.  
  133. vector<int> ans;
  134. void dfs2(int u, int p, int tot){
  135.     tot ^= xum[u];
  136.     if(tot == 0 && color[u] == 0){
  137.         ans.pb(u);
  138.     }
  139.     for(int v : adj[u]){
  140.         if(v != p){
  141.             dfs2(v, u, tot^grundy[v]);
  142.         }
  143.     }  
  144. }
  145.  
  146. void solve(){
  147.     cin >> n;
  148.     for(int i = 1; i<=n; i++){
  149.         cin >> color[i];
  150.     }
  151.     for(int i = 1; i<n; i++){
  152.         int a, b;
  153.         cin >> a >> b;
  154.         adj[a].pb(b);
  155.         b[adj].pb(a);
  156.     }
  157.     dfs(1, 0);
  158.     //for(int i = 1; i<=n; i++){
  159.         //cout << grundy[i] << " " ;
  160.     //} cout << "\n";
  161.     //for(int i = 1; i<=n; i++){
  162.         //cout << xum[i] << " " ;
  163.     //} cout << "\n";
  164.  
  165.  
  166.     if(grundy[1] == 0){
  167.         cout << "-1\n";
  168.     }else{
  169.         dfs2(1, 0, 0);
  170.         sort(all(ans));
  171.         for(int x : ans){
  172.             cout << x << "\n";
  173.         }
  174.     }
  175. }
  176.  
  177. int main(){
  178.   cin.tie(0) -> sync_with_stdio(0);
  179.  
  180.   int T = 1;
  181.   //cin >> T;
  182.   while(T--){
  183.         solve();
  184.   }
  185.   return 0;
  186. }
  187.  
  188.  
  189.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement