fork download
  1. // ROOT : DRAGON3012009
  2. #include <bits/stdc++.h>
  3. #define ll long long
  4. #define el "\n"
  5. #define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  6. #define __ROOT__ int main()
  7. #define fi first
  8. #define se second
  9. #define M 1000000007
  10. #define MAXN 100001
  11. #define GIOIHAN 1000001
  12. #define BLOCK_SIZE 425
  13. #define MAX_NODE 1001001
  14. #define LOG 19
  15. #define ALPHA_SIZE 26
  16. #define BASE 311
  17. #define NAME "file"
  18. #define compare(v) sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); // dùng để nén sort mảng compare
  19. using namespace std;
  20. const ll MOD[] = {(ll)1e9 + 2277, (ll)1e9 + 5277, (ll)1e9 + 8277, (ll)1e9 + 9277, (ll) 1e9 + 7 };
  21. const ll NMOD = 1;
  22. const int dx[] = {-1, 0, 1,0};
  23. const int dy[] = {0, 1, 0, -1};
  24. //**Variable**//
  25. ll n, q ;
  26. ll arr[MAXN];
  27. vector<ll> adj[MAXN];
  28. ll high[MAXN] ;
  29. ll tour[MAXN] ;
  30. ll fin[MAXN] ;
  31. ll par[MAXN ] ;
  32. ll st [MAXN] ;
  33. ll chainID[MAXN] ;
  34. ll chainHead[MAXN] ;
  35. ll sz[MAXN] ;
  36. ll curchain = 1, timedfs = 0 ; // 0 : trang , 1 : den
  37. //**Struct**//
  38. struct Seg {
  39. ll val[MAXN<< 2 ] ;
  40. void update(ll id, ll l, ll r,ll pos ) {
  41. if(l == r ) {
  42. val[id] ^=1 ; // cập nhất 0 thành 1 , 1 thành 0
  43. } else {
  44. ll m = l + r >> 1 ;
  45. if(m>= pos ) update(id<<1,l, m, pos ) ;
  46. else update(id<<1|1, m + 1, r,pos ) ;
  47. val[id] = max(val[id<<1 ], val[id<<1|1]) ;
  48. }
  49. }
  50. ll get(ll id, ll l, ll r, ll u, ll v ) {
  51. if(u > r || v < l ) return -1 ;
  52. if(l == r ) return l ;
  53. ll ans = -1 ;
  54. ll m = l + r >> 1;
  55. if(val[id<< 1 ] >= 1 ) ans = get(id<<1, l, m, u, v ) ;
  56. if(ans == -1 && val[id<<1|1] >=1 ) ans = get(id<<1|1, m + 1, r, u, v ) ; // walk on tree, thử trường hợp gần trước rồi mới đến xa
  57. return ans ;
  58. }
  59. } seg;
  60. //**Function**//
  61. void dfs(ll u, ll p ) {
  62. sz[u] = 1 ;
  63. for(ll v : adj[u]) {
  64. if(v == p ) continue ;
  65. par[v] = u ;
  66. high[v] = high[u] + 1 ;
  67. dfs(v, u ) ;
  68. sz[u] += sz[v];
  69. }
  70. }
  71. void hld(ll u, ll p ) {
  72. if(!chainHead[curchain]) {
  73. chainHead[curchain ] = u ;
  74. }
  75. st[u] = ++ timedfs ;
  76. tour[timedfs] = u ;
  77. chainID[u] = curchain ;
  78. ll nxt = 0 ;
  79. for(ll v : adj[u]) {
  80. if(v == p ) continue ;
  81. if(nxt == 0 || sz[v] > sz[nxt]) nxt = v;
  82. }
  83. if(nxt ) hld(nxt, u ) ;
  84. for(ll v : adj[u]) {
  85. if(v != p && v != nxt ) {
  86. curchain ++ ;
  87. hld(v, u ) ;
  88. }
  89. }
  90. fin[u] =timedfs;
  91. }
  92. ll LCA(ll u, ll v ) {
  93. while(chainID[u] != chainID[v]) {
  94. if(chainID[u] > chainID[v]) u = par[chainHead[chainID[u]]];
  95. else v = par[chainHead[chainID[v]]];
  96. }
  97. return (high[u] > high[v ] ? v : u );
  98. }
  99. ll query(ll u, ll v ) {
  100. ll lca = LCA(u, v ) ;
  101. ll res = -1 ;
  102. while(chainID[u] != chainID[lca]) {
  103. ll pos= seg.get(1, 1, n, st[chainHead[chainID[u]]], st[u]) ; // cái này mình tìm cạnh đầu tiên suát hiện từ cha của nhánh đến vị trí hiện tại và tìm ngược lên
  104. if(pos != -1 ) res = tour[pos] ; // nên kết quả luôn là vị trí đầu tiền
  105. u = par[chainHead[chainID[u]]] ;
  106. }
  107. while(chainID[v] != chainID[lca]) {
  108. ll pos= seg.get(1, 1, n, st[chainHead[chainID[v]]], st[v]) ;
  109. if(pos != -1 ) res = tour[pos] ;
  110. v = par[chainHead[chainID[v]]] ;
  111. }
  112. if(high[u] > high[v]) swap(u, v) ;
  113. ll pos = seg.get(1,1,n, st[u], st[v]) ;
  114. if(pos != -1 ) res = tour[pos] ;
  115. return res ;
  116. }
  117. void init() {
  118. cin>>n>> q ;
  119. for(ll i = 0 ; i < n - 1 ; i ++ ) {
  120. ll x, y ;
  121. cin>>x>> y ;
  122. adj[x].push_back(y);
  123. adj[y].push_back(x);
  124. }
  125. dfs(1, 1 ) ;
  126. hld(1, 1 ) ; // khởi tạo nè
  127. }
  128.  
  129. void solve() {
  130. for(ll i = 0 ; i < q ; i ++ ) {
  131. ll t,x ;
  132. cin >> t>> x;
  133. if( t== 0 ) {
  134. seg.update(1,1,n, st[x]) ; // update lại seg theo thứ tự đường đi euler
  135. } else {
  136. cout<<query(x, 1ll ) <<el ; // trả lời query
  137. }
  138. }
  139. }
  140.  
  141. __ROOT__ {
  142. // freopen(NAME".inp" , "r" , stdin);
  143. // freopen(NAME".out" , "w", stdout) ;
  144. fast;
  145. init();
  146. solve();
  147. }
  148.  
  149.  
Success #stdin #stdout 0.01s 10848KB
stdin
9 8
1 2
1 3
2 4
2 9
5 9
7 9
8 9
6 8
1 3
0 8
1 6
1 7
0 2
1 9
0 2
1 9
stdout
-1
8
-1
2
-1