Advertisement
FyanRu

Untitled

Jul 15th, 2024
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. #include <algorithm>
  2. #include <array>
  3. #include <bitset>
  4. #include <cassert>
  5. #include <chrono>
  6. #include <complex>
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <deque>
  10. #include <iomanip>
  11. #include <iostream>
  12. #include <iterator>
  13. #include <list>
  14. #include <map>
  15. #include <memory>
  16. #include <numeric>
  17. #include <queue>
  18. #include <random>
  19. #include <set>
  20. #include <stack>
  21. #include <string>
  22. #include <tuple>
  23. #include <vector>
  24. using namespace std;
  25. #define sz(x) (int) (x).size()
  26.  
  27. const int BUF_SZ = 1 << 15;
  28. inline namespace Input {
  29. char buf[BUF_SZ];int pos;int len;
  30. char next_char() {
  31. if (pos == len) {pos = 0;
  32. len = (int)fread(buf, 1, BUF_SZ, stdin);
  33. if (!len) { return EOF; }}
  34. return buf[pos++];}
  35. int read_int() {
  36. int x;char ch;int sgn = 1;
  37. while (!isdigit(ch = next_char())) {
  38. if (ch == '-') { sgn *= -1; }}
  39. x = ch - '0';
  40. while (isdigit(ch = next_char())) { x = x * 10 + (ch - '0'); }
  41. return x * sgn;}
  42. }
  43. inline namespace Output {
  44. char buf[BUF_SZ];int pos;
  45. void flush_out() {fwrite(buf, 1, pos, stdout);pos = 0;}
  46. void write_char(char c) {
  47. if (pos == BUF_SZ) { flush_out(); }
  48. buf[pos++] = c;}
  49. void write_int(int x) {
  50. static char num_buf[100];
  51. if (x < 0) {write_char('-');x *= -1;}
  52. int len = 0;
  53. for (; x >= 10; x /= 10) { num_buf[len++] = (char)('0' + (x % 10)); }
  54. write_char((char)('0' + x));
  55. while (len) { write_char(num_buf[--len]); }
  56. write_char('\n');}
  57. void init_output() { assert(atexit(flush_out) == 0); }
  58. }
  59.  
  60. const int inf=9;
  61.  
  62. struct sparsemin { vector<int> a; int h; vector<vector<int>> st; sparsemin() {} sparsemin(vector<int>& arr) : a(arr), h(log2(a.size()) + 1), st(h + 1) { for (int i = 0; i < a.size(); i++) st[0].push_back(i); for (int i = 1; i <= h; i++) for (int j = 0; j + (1 << i) <= arr.size(); j++) st[i].push_back(a[st[i-1][j]] < a[st[i-1][j + (1 << (i-1))]] ? st[i-1][j] : st[i-1][j + (1 << (i-1))]); } int rmq(int l, int r) { int i = log2(r - l + 1); return a[st[i][l]] < a[st[i][r - (1 << i) + 1]] ? st[i][l] : st[i][r - (1 << i) + 1]; } };
  63. struct tree {
  64. int n; vector<vector<array<int,2>>> adj; vector<int> par, etour, tin, tot, dep, dtour; sparsemin st;
  65. tree() {}
  66. void init(int n1) { adj.resize(0); par.resize(0); etour.resize(0); tin.resize(0); tot.resize(0); dep.resize(0); dtour.resize(0); n = n1; adj.resize(n); }
  67. void add_edge(int u, int v, int w = 1) { adj[u].push_back({v, w}); adj[v].push_back({u, w}); }
  68. void go() { par.resize(n); tin.resize(n); tot.resize(n); dep.resize(n); dfs(0, 0, 0); for (int i = 0; i < etour.size(); i++) dtour.push_back(dep[etour[i]]); st = sparsemin(dtour); }
  69. void dfs(int v, int p, int d) { par[v] = p, dep[v] = d; tin[v] = etour.size(); etour.push_back(v); for (auto e : adj[v]) { int i = e[0], w = e[1]; if (i == p) continue; dfs(i, v, d + w); etour.push_back(v); } tot[v] = etour.size(); etour.push_back(v); }
  70. int lca(int l, int r) { int mnv = min(tin[l], tin[r]); int mxv = max(tin[l], tin[r]); return etour[st.rmq(mnv, mxv)]; }
  71. int dist(int u, int v) { if (u==-1 || v==-1) {return 0;} return dep[u] + dep[v] - dep[lca(u, v)]; }
  72. };
  73.  
  74. const int mxn=5e5+5;
  75.  
  76. int n,q,c[mxn],qr[mxn][4],np;
  77. tree t;
  78.  
  79. void chmax(int &x, int &y, int x1, int y1) {
  80. if (x==-1 || y==-1) {
  81. x=x1, y=y1;
  82. return;
  83. }
  84. if (x1==-1 || y1==-1) {
  85. return;
  86. }
  87. if (t.dist(x1,y1)>=t.dist(x,y)) {
  88. x=x1;
  89. y=y1;
  90. }
  91. }
  92.  
  93. vector<int> aux;
  94.  
  95. struct node {
  96. node *l=0,*r=0;
  97. int lo,hi;
  98. int x=-1,y=-1,xd=-1,yd=-1;
  99. node() {
  100. x=-1,y=-1,xd=-1,yd=-1;
  101. }
  102. node(int i) {x=i,y=i,lo=i,hi=i;}
  103. node(int lo,int hi) : lo(lo),hi(hi) {
  104. x=-1,y=-1,xd=-1,yd=-1;
  105. }
  106. void push() {
  107. if (!l) {
  108. l = new node(lo,(lo+hi)/2);
  109. r = new node((lo+hi)/2+1,hi);
  110. }
  111. }
  112. void pull() {
  113. if (!l) return;
  114. x=-1,y=-1;
  115. aux = {l->x,l->y,r->x,r->y};
  116. for (int i=0; i<sz(aux); i++) {
  117. for (int j=i; j<sz(aux); j++) {
  118. chmax(x,y,aux[i],aux[j]);
  119. }
  120. }
  121. xd=-1,yd=-1;
  122. aux = {l->x,l->y,r->x,r->y,l->xd,l->yd,r->xd,r->yd};
  123. for (int i=0; i<sz(aux); i++) {
  124. for (int j=i+1; j<sz(aux); j++) {
  125. if (aux[i]!=-1 && aux[j]!=-1 && c[aux[i]] != c[aux[j]]) {
  126. chmax(xd,yd,aux[i],aux[j]);
  127. }
  128. }
  129. }
  130. }
  131. void point_set(int I, int X, int Y) {
  132. if (lo==I && I==hi) {
  133. x=X, y=Y;
  134. if (X!=-1 && Y!=-1 && c[X] != c[Y]) {
  135. xd=X,yd=Y;
  136. } else {
  137. xd=-1,yd=-1;
  138. }
  139. return;
  140. }
  141. if (lo>I || hi<I) return;
  142. push();
  143. if (I<=(lo+hi)/2) l->point_set(I,X,Y);
  144. else r->point_set(I,X,Y);
  145. pull();
  146. }
  147. };
  148.  
  149. node crt[mxn], trt;
  150.  
  151. void solve() {
  152. q = read_int();
  153. c[0] = read_int();
  154. n = 0;
  155. t.init(q+5);
  156. np=1;
  157. for (int i=0; i<q; i++) {
  158. qr[i][0] = read_int();
  159. qr[i][1] = read_int();
  160. qr[i][2] = read_int();
  161. if (!qr[i][0]) {
  162. int d = read_int();
  163. t.add_edge(qr[i][1]-1,np++,d);
  164. n++;
  165. qr[i][1]=np;
  166. }
  167. qr[i][1]--;
  168. }
  169. t.go();
  170. for (int i=0; i<=q; i++) {
  171. crt[i] = node(0,mxn);
  172. }
  173. trt = node(0,mxn);
  174. crt[c[0]].point_set(0,0,0);
  175. trt.point_set(c[0],crt[c[0]].x,crt[c[0]].y);
  176. for (int i=0; i<q; i++) {
  177. int tr=qr[i][0],x=qr[i][1],ci=qr[i][2];
  178. int pcx = c[x];
  179. c[x] = ci;
  180. if (tr) {
  181. crt[pcx].point_set(x,-1,-1);
  182. trt.point_set(pcx,crt[pcx].x,crt[pcx].y);
  183. }
  184.  
  185. crt[ci].point_set(x,x,x);
  186. trt.point_set(ci,crt[ci].x,crt[ci].y);
  187. write_int(t.dist(trt.xd,trt.yd));
  188. }
  189. }
  190.  
  191. signed main() {
  192. init_output();
  193.  
  194. int t = read_int();
  195. while (t--) {
  196. solve();
  197. }
  198.  
  199. return 0;
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement