Advertisement
FyanRu

Untitled

Jul 17th, 2024
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.53 KB | None | 0 0
  1. #pragma GCC optimize("O3,unroll-loops")
  2. #include <algorithm>
  3. #include <array>
  4. #include <bitset>
  5. #include <cassert>
  6. #include <chrono>
  7. #include <complex>
  8. #include <cstdio>
  9. #include <cstring>
  10. #include <deque>
  11. #include <iomanip>
  12. #include <iostream>
  13. #include <iterator>
  14. #include <list>
  15. #include <map>
  16. #include <memory>
  17. #include <numeric>
  18. #include <queue>
  19. #include <random>
  20. #include <set>
  21. #include <stack>
  22. #include <string>
  23. #include <tuple>
  24. #include <vector>
  25. using namespace std;
  26. #define sz(x) (int) (x).size()
  27. #define i64 int64_t
  28. #define all(x) (x).begin(), (x).end()
  29.  
  30. int log2_floor(unsigned long long i) {
  31. return i ? __builtin_clzll(1) - __builtin_clzll(i) : -1;
  32. }
  33.  
  34. const int BUF_SZ = 1 << 15;
  35. inline namespace Input {
  36. char buf[BUF_SZ];int pos;int len;
  37. char next_char() {
  38. if (pos == len) {pos = 0;
  39. len = (int)fread(buf, 1, BUF_SZ, stdin);
  40. if (!len) { return EOF; }}
  41. return buf[pos++];}
  42. i64 read_int() {
  43. i64 x;char ch;int sgn = 1;
  44. while (!isdigit(ch = next_char())) {
  45. if (ch == '-') { sgn *= -1; }}
  46. x = ch - '0';
  47. while (isdigit(ch = next_char())) { x = x * 10ll + (ch - '0'); }
  48. return x * sgn;}
  49. }
  50. inline namespace Output {
  51. char buf[BUF_SZ];int pos;
  52. void flush_out() {fwrite(buf, 1, pos, stdout);pos = 0;}
  53. void write_char(char c) {
  54. if (pos == BUF_SZ) { flush_out(); }
  55. buf[pos++] = c;}
  56. void write_int(i64 x) {
  57. static char num_buf[100];
  58. if (x < 0) {write_char('-');x *= -1;}
  59. int len = 0;
  60. for (; x >= 10; x /= 10) { num_buf[len++] = (char)('0' + (x % 10)); }
  61. write_char((char)('0' + x));
  62. while (len) { write_char(num_buf[--len]); }
  63. write_char('\n');}
  64. void init_output() { assert(atexit(flush_out) == 0); }
  65. }
  66.  
  67. const int inf = 9;
  68.  
  69. struct sparsemin {
  70. vector<i64> a;
  71. int h;
  72. vector<vector<i64>> st;
  73. sparsemin() {}
  74. sparsemin(vector<i64>& arr) : a(arr), h(log2(a.size()) + 1), st(h + 1) {
  75. for (int i = 0; i < a.size(); i++) st[0].push_back(i);
  76. for (int i = 1; i <= h; i++)
  77. for (int j = 0; j + (1 << i) <= arr.size(); j++)
  78. 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))]);
  79. }
  80. int rmq(int l, int r) {
  81. int i = log2_floor(r - l + 1);
  82. return a[st[i][l]] < a[st[i][r - (1 << i) + 1]] ? st[i][l] : st[i][r - (1 << i) + 1];
  83. }
  84. };
  85.  
  86. const int FAKE = 5e5+3;
  87.  
  88. vector<array<i64,2>> adj[FAKE];
  89. int etour[4*FAKE],tin[FAKE],tot[FAKE];
  90. i64 dtour[4*FAKE], dep[FAKE];
  91. int tourp = 0;
  92.  
  93. void tinit(int n) {
  94. for (int i=0; i<n; i++) {
  95. adj[i].resize(0);
  96. }
  97. tourp = 0;
  98. }
  99.  
  100. void add_edge(int u, int v, i64 w) {
  101. adj[u].push_back({v, w});
  102. adj[v].push_back({u, w});
  103. }
  104.  
  105. void dfs(int v, int p, i64 d) {
  106. dep[v] = d;
  107. tin[v] = tourp;
  108. etour[tourp++] = v;
  109. for (const array<i64,2> &e : adj[v]) {
  110. if (e[0] == p) continue;
  111. dfs(e[0],v,d+e[1]);
  112. etour[tourp++] = v;
  113. }
  114. tot[v] = tourp;
  115. etour[tourp++] = v;
  116. }
  117.  
  118. const int LG = 20;
  119. int sparsetable[LG][4*FAKE];
  120. void init_sparse() {
  121. dfs(0, 0, 0);
  122. for (int i=0; i<tourp; i++) {
  123. dtour[i] = dep[etour[i]];
  124. }
  125. for (int i=0; i<tourp; i++) {
  126. sparsetable[0][i] = i;
  127. }
  128. for (int i=1; i<=LG; i++) {
  129. for (int j=0; j + (1 << i) <= tourp; j++) {
  130. sparsetable[i][j] =
  131. (dtour[sparsetable[i-1][j]] < dtour[sparsetable[i-1][j + (1 << (i-1))]]
  132. ? sparsetable[i-1][j] : sparsetable[i-1][j + (1 << (i-1))]);
  133. }
  134. }
  135. }
  136.  
  137. int rmq(int l, int r) {
  138. int i = log2_floor(r-l+1);
  139. return (dtour[sparsetable[i][l]] < dtour[sparsetable[i][r-(1<<i)+1]]
  140. ? sparsetable[i][l] : sparsetable[i][r-(1<<i)+1]);
  141. }
  142. int lca(int u, int v) {
  143. return etour[rmq(min(tin[u],tin[v]),max(tot[u],tot[v]))];
  144. }
  145. i64 dist(int u, int v) {
  146. if (u == FAKE || v == FAKE) {return -69;}
  147. return dep[u] + dep[v] - 2*dep[lca(u,v)];
  148. }
  149.  
  150. const int mxn = 5e5 + 5;
  151.  
  152. int n, q, c[mxn], qr[mxn][4], np;
  153.  
  154. void chmax(int &x, int &y, int x1, int y1) {
  155. if (dist(x1, y1) >= dist(x, y)) {
  156. x = x1;
  157. y = y1;
  158. }
  159. }
  160.  
  161. const int MM=10;
  162.  
  163. int lo[MM*mxn],hi[MM*mxn],x[MM*mxn],y[MM*mxn],xd[MM*mxn],yd[MM*mxn],CXD[MM*mxn];
  164. int lc[MM*mxn],rc[MM*mxn];
  165.  
  166. int nx = 0;
  167. int create_node(int cxd) {
  168. CXD[nx]=cxd; x[nx]=FAKE; y[nx]=FAKE; lc[nx]=-1; rc[nx]=-1; xd[nx]=FAKE; yd[nx]=FAKE;
  169. return nx++;
  170. }
  171. int create_node(int l, int h, int cxd) {
  172. lo[nx]=l; hi[nx]=h;
  173. return create_node(cxd);
  174. }
  175. void pull(int v) {
  176. int &xv=x[v],&yv=y[v],&xdv=xd[v],&ydv=yd[v];
  177. xv=FAKE,yv=FAKE,xdv=FAKE,ydv=FAKE;
  178. if (lc[v]==-1 && rc[v]==-1) {return;}
  179. if (rc[v]==-1) {
  180. xv=x[lc[v]]; yv=y[lc[v]];
  181. if (CXD[v]) {xdv=xd[lc[v]],ydv=yd[lc[v]];}
  182. return;
  183. }
  184. if (lc[v]==-1) {
  185. xv=x[rc[v]]; yv=y[rc[v]];
  186. if (CXD[v]) {xdv=xd[rc[v]],ydv=yd[rc[v]];}
  187. return;
  188. }
  189. if (CXD[v]) {
  190. int lx=x[lc[v]],rx=x[rc[v]],ly=y[lc[v]],ry=y[rc[v]];
  191. int lxd=xd[lc[v]],rxd=xd[rc[v]],lyd=yd[lc[v]],ryd=yd[rc[v]];
  192. chmax(xdv,ydv,lx,rx); chmax(xdv,ydv,lx,ry); chmax(xdv,ydv,ly,rx);
  193. chmax(xdv,ydv,ly,ry); chmax(xdv,ydv,lxd,lyd); chmax(xdv,ydv,rxd,ryd);
  194. int tp=xdv; xv=tp; tp=ydv; yv=tp;
  195. if (c[lx]!=c[ly]) {chmax(xdv,ydv,lx,ly);}
  196. if (c[lx]!=c[ly]) {chmax(xdv,ydv,lx,ly);}
  197. chmax(xv,yv,lx,ly);
  198. chmax(xv,yv,rx,ry);
  199. } else {
  200. int lx=x[lc[v]],rx=x[rc[v]],ly=y[lc[v]],ry=y[rc[v]];
  201. chmax(xv,yv,lx,ly); chmax(xv,yv,lx,rx); chmax(xv,yv,lx,ry);
  202. chmax(xv,yv,ly,rx); chmax(xv,yv,ly,ry); chmax(xv,yv,rx,ry);
  203. }
  204.  
  205. }
  206. void point_set(int v, int I, int X, int Y) {
  207. if (lo[v]==I && hi[v]==I) {x[v]=X,y[v]=Y;xd[v]=FAKE;yd[v]=FAKE; return;}
  208. if (I<=(lo[v]+hi[v])/2) {
  209. if (lc[v]==-1) {lc[v] = create_node(lo[v],(lo[v]+hi[v])/2,CXD[v]);}
  210. point_set(lc[v],I,X,Y);
  211. } else {
  212. if (rc[v]==-1) {rc[v] = create_node((lo[v]+hi[v])/2+1,hi[v],CXD[v]);}
  213. point_set(rc[v],I,X,Y);
  214. }
  215. pull(v);
  216. }
  217.  
  218. int crt[mxn], trt;
  219. vector<int> col[mxn];
  220.  
  221. void solve() {
  222. nx=0;
  223. for (int i=0; i<=q; i++) {col[i].resize(0);}
  224. q = read_int();
  225. c[0] = read_int();
  226. n = 0;
  227. col[c[0]].push_back(0);
  228. tinit(q + 1);
  229. np = 1;
  230. for (int i = 0; i < q; i++) {
  231. qr[i][0] = read_int();
  232. qr[i][1] = read_int();
  233. qr[i][2] = read_int();
  234. if (!qr[i][0]) {
  235. i64 d = read_int();
  236. add_edge(qr[i][1] - 1, np++, d);
  237. n++;
  238. qr[i][1] = np;
  239. }
  240. qr[i][1]--;
  241. col[qr[i][2]].push_back(qr[i][1]);
  242. }
  243. for (int i=0; i<=q; i++) {
  244. sort(all(col[i]));
  245. col[i].erase(unique(all(col[i])),col[i].end());
  246. }
  247.  
  248. init_sparse();
  249.  
  250. for (int i = 0; i <= q; i++) {
  251. crt[i] = create_node(0, sz(col[i])+1,0);
  252. }
  253. trt = create_node(0, q + 1,1);
  254. point_set(crt[c[0]],0, 0, 0);
  255. point_set(trt, c[0], x[crt[c[0]]], y[crt[c[0]]]);
  256. for (int i = 0; i < q; i++) {
  257. int tr = qr[i][0], xx = qr[i][1], ci = qr[i][2];
  258. int pcx = c[xx];
  259. c[xx] = ci;
  260. if (tr) {
  261. int xtv = lower_bound(all(col[pcx]),xx)-col[pcx].begin();
  262. point_set(crt[pcx], xtv, FAKE, FAKE);
  263. point_set(trt, pcx, x[crt[pcx]], y[crt[pcx]]);
  264. }
  265. int xtv = lower_bound(all(col[ci]),xx) - col[ci].begin();
  266. point_set(crt[ci],xtv, xx, xx);
  267. point_set(trt, ci, x[crt[ci]], y[crt[ci]]);
  268. write_int(max(dist(xd[trt], yd[trt]),0ll));
  269. }
  270. }
  271.  
  272. signed main() {
  273. init_output();
  274.  
  275. int t = read_int();
  276. while (t--) {
  277. solve();
  278. }
  279.  
  280. return 0;
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement