fork download
  1. # include <iostream>
  2. # include <cmath>
  3. # include <algorithm>
  4. # include <stdio.h>
  5. # include <string>
  6. # include <vector>
  7. using namespace std;
  8. int get_point_mn(int x);
  9. int get_last(int l, int r, int ll, int rr, int x, int y);
  10. long long get_sum(int l, int r, int ll, int rr, int x, int y);
  11.  
  12. const int N = 250005;
  13.  
  14.  
  15. struct NODE {
  16. int mn, cnt_mn;
  17. int qmn;
  18. long long sum, qsum;
  19. bool ob;
  20. NODE () {
  21. mn = cnt_mn = sum = qsum = 0;
  22. ob = false;
  23. }
  24.  
  25. } t[3 * N];
  26.  
  27. int ans_query7;
  28. int n, m, sz, group, timer, sz_pred;
  29. string bin_ed;
  30. int vert_cnt[3 * N];
  31. int max_tout[3 * N];
  32. int qob[N];
  33. int tin[N], tout[N], poc[N];
  34. vector<pair<int, int> > v[N];
  35. pair<int, int> ed[N];
  36. int depth[N], first_pos[N], poc2[N + N], pred[19][N + N], max_step[N + N];
  37. int pw[30];
  38. bool comp[N];
  39.  
  40. void dfs(int x, int y) {
  41. tin[x] = ++timer;
  42. depth[x] = depth[y] + 1;
  43. poc[timer] = x;
  44. poc2[++sz_pred] = x;
  45. first_pos[x] = sz_pred;
  46. for (int i = 0; i < v[x].size(); ++i) {
  47. int to = v[x][i].first;
  48. if (to != y) {
  49. dfs(to, x);
  50. poc2[++sz_pred] = x;
  51. }
  52. }
  53. tout[x] = timer;
  54. return;
  55. }
  56.  
  57. void build_sparse_table() {
  58. for (int i = 2; i <= sz_pred; ++i)
  59. max_step[i] = max_step[(i >> 1)] + 1;
  60. for (int i = 1; i <= sz_pred; ++i) {
  61. pred[0][i] = poc2[i];
  62. }
  63. for (int i = 0; i <= 25; ++i)
  64. pw[i] = (1 << i);
  65. for (int it = 1; it <= max_step[sz_pred]; ++it) {
  66. for (int j = 1; j <= sz_pred - pw[it] + 1; ++j) {
  67. pred[it][j] = pred[it - 1][j];
  68. if (depth[pred[it][j]] > depth[pred[it - 1][j + pw[it - 1]]]) pred[it][j] = pred[it - 1][j + pw[it - 1]];
  69. }
  70. }
  71. return;
  72. }
  73.  
  74. int get_lca(int x, int y) {
  75. x = first_pos[x];
  76. y = first_pos[y];
  77. if (x > y) swap(x, y);
  78. int len = max_step[y - x + 1];
  79. int xx = pred[len][x];
  80. int yy = pred[len][y - pw[len] + 1];
  81. if (depth[xx] <= depth[yy]) return xx;
  82. return yy;
  83. }
  84.  
  85. int get_number_of_edges(int x, int y, int xx, int yy) {
  86. int z = get_lca(x, y);
  87. if (tout[x] >= tout[y]) return yy - xx;
  88. return xx + yy - (get_point_mn(tin[z]) << 1);
  89. }
  90.  
  91. /////////////////////// Segment Tree for Components
  92.  
  93. void tree_update_vertex(int x, int y) {
  94. x += sz - 1;
  95. vert_cnt[x] = y;
  96. x >>= 1;
  97. while (x) {
  98. vert_cnt[x] = vert_cnt[x + x] + vert_cnt[x + x + 1];
  99. x >>= 1;
  100. }
  101. return;
  102. }
  103.  
  104. int get_last_vertex(int l, int r, int ll, int rr, int x) {
  105. if (l > r || ll > r || l > rr || ll > rr || !vert_cnt[x]) return 0;
  106. if (l == r) return l;
  107. int mid = (l + r) >> 1;
  108. int res = get_last_vertex(mid + 1, r, ll, rr, x + x + 1);
  109. if (res) return res;
  110. return get_last_vertex(l, mid, ll, rr, x + x);
  111. }
  112.  
  113. int get_first_vertex(int l, int r, int ll, int rr, int x) {
  114. if (l > r || ll > r || l > rr || ll > rr || !vert_cnt[x]) return 0;
  115. if (l == r) return l;
  116. int mid = (l + r) >> 1;
  117. int res = get_first_vertex(l, mid, ll, rr, x + x);
  118. if (res) return res;
  119. return get_first_vertex(mid + 1, r, ll, rr, x + x + 1);
  120. }
  121.  
  122. int FIR = 1e9, SEC = -1e9;
  123.  
  124. void update_component(int x) {
  125. comp[x] ^= 1;
  126. tree_update_vertex(tin[x], comp[x]);
  127. int xx = get_last_vertex(1, sz, 1, tin[x] - 1, 1);
  128. int xx1, xx2, xx3;
  129. xx1 = xx2 = xx3 = -1;
  130. if (xx) {
  131. xx1 = get_point_mn(tin[poc[xx]]), xx3 = get_point_mn(tin[x]);
  132. if (comp[x]) ans_query7 += get_number_of_edges(poc[xx], x, xx1, xx3);
  133. else ans_query7 -= get_number_of_edges(poc[xx], x, xx1, xx3);
  134. }
  135. int yy = get_first_vertex(1, sz, tin[x] + 1, n, 1);
  136. if (yy) {
  137. xx2 = get_point_mn(tin[poc[yy]]);
  138. if (xx3 == -1) xx3 = get_point_mn(tin[x]);
  139. if (comp[x]) ans_query7 += get_number_of_edges(x, poc[yy], xx3, xx2);
  140. else ans_query7 -= get_number_of_edges(x, poc[yy], xx3, xx2);
  141. }
  142. if (comp[x] == 1) {
  143. if (tin[x] < FIR) FIR = tin[x];
  144. if (tin[x] > SEC) SEC = tin[x];
  145. } else {
  146. if (FIR == SEC) FIR = 1e9, SEC = -1e9;
  147. else if (FIR == tin[x]) FIR = yy;
  148. else if (SEC == tin[x]) SEC = xx;
  149. }
  150. if (xx && yy) {
  151. xx = poc[xx];
  152. yy = poc[yy];
  153. if (xx1 == -1) xx1 = get_point_mn(tin[xx]);
  154. if (xx2 == -1) xx2 = get_point_mn(tin[yy]);
  155. if (comp[x]) ans_query7 -= get_number_of_edges(xx, yy, xx1, xx2);
  156. else ans_query7 += get_number_of_edges(xx, yy, xx1, xx2);
  157. }
  158. return;
  159. }
  160.  
  161. bool is_there_somebody(int x, bool y) {
  162. if (!y) {
  163. x = get_last(1, sz, 1, tin[x], 1, tout[x]);
  164. if (!x) x = 1;
  165. x = poc[x];
  166. }
  167. return (bool)(get_sum(1, sz, tin[x], tout[x], 1, get_point_mn(tin[x])) > 0);
  168. }
  169.  
  170. /////////////////////// Closest blocked edge
  171.  
  172. void update_edge(int x, int y) {
  173. x += sz - 1;
  174. max_tout[x] = y;
  175. x >>= 1;
  176. while (x) {
  177. max_tout[x] = max_tout[x + x];
  178. if (max_tout[x + x + 1] > max_tout[x]) max_tout[x] = max_tout[x + x + 1];
  179. x >>= 1;
  180. }
  181. return;
  182. }
  183.  
  184. int get_last(int l, int r, int ll, int rr, int x, int y) {
  185. if (l > r || ll > r || l > rr || ll > rr || max_tout[x] < y) return 0;
  186. if (l == r) return l;
  187. int mid = (l + r) >> 1;
  188. int res = get_last(mid + 1, r, ll, rr, x + x + 1, y);
  189. if (res) return res;
  190. return get_last(l, mid, ll, rr, x + x, y);
  191. }
  192.  
  193. ////////////////////// Segment Tree for Queries
  194.  
  195. ////////// Update NODE
  196.  
  197. void push(int x) {
  198. int xx = t[x].mn;
  199. if (t[x].qmn) {
  200. int z = t[x].qmn;
  201. t[x].qmn = 0;
  202. t[x + x].mn += z;
  203. t[x + x + 1].mn += z;
  204. t[x + x].qmn += z;
  205. t[x + x + 1].qmn += z;
  206. }
  207. if (t[x].ob) {
  208. t[x].ob = false;
  209. if (t[x + x].mn == xx) {
  210. t[x + x].sum = t[x + x].qsum = 0;
  211. t[x + x].ob = true;
  212. }
  213. if (t[x + x + 1].mn == xx) {
  214. t[x + x + 1].sum = t[x + x + 1].qsum = 0;
  215. t[x + x + 1].ob = true;
  216. }
  217. }
  218. if (t[x].qsum) {
  219. long long z = t[x].qsum;
  220. t[x].qsum = 0;
  221. if (t[x + x].mn == xx) {
  222. t[x + x].sum += (t[x + x].cnt_mn * z);
  223. t[x + x].qsum += z;
  224. }
  225. if (t[x + x + 1].mn == xx) {
  226. t[x + x + 1].sum += (t[x + x + 1].cnt_mn * z);
  227. t[x + x + 1].qsum += z;
  228. }
  229. }
  230. return;
  231. }
  232.  
  233. void update_NODE(int x) {
  234. t[x].mn = t[x + x].mn;
  235. t[x].cnt_mn = t[x + x].cnt_mn;
  236. t[x].sum = t[x + x].sum;
  237. if (t[x + x + 1].mn < t[x].mn) {
  238. t[x].mn = t[x + x + 1].mn;
  239. t[x].cnt_mn = t[x + x + 1].cnt_mn;
  240. t[x].sum = t[x + x + 1].sum;
  241. } else if (t[x + x + 1].mn == t[x].mn) {
  242. t[x].cnt_mn += t[x + x + 1].cnt_mn;
  243. t[x].sum += t[x + x + 1].sum;
  244. }
  245. return;
  246. }
  247.  
  248. /////////////////////
  249.  
  250. void update_cnt(int l, int r, int ll, int rr, int x, int y) {
  251. if (l > r || ll > r || l > rr || ll > rr) return;
  252. if (l >= ll && r <= rr) {
  253. t[x].mn += y;
  254. t[x].qmn += y;
  255. return;
  256. }
  257. int mid = (l + r) >> 1;
  258. push(x);
  259. update_cnt(l, mid, ll, rr, x + x, y);
  260. update_cnt(mid + 1, r, ll, rr, x + x + 1, y);
  261. update_NODE(x);
  262. return;
  263. }
  264.  
  265. int global_pos1;
  266.  
  267. void update_sum_point(int l, int r, int ll, int x, long long y) {
  268. if (l == r) {
  269. global_pos1 = t[x].mn;
  270. t[x].sum += y;
  271. return;
  272. }
  273. int mid = (l + r) >> 1;
  274. push(x);
  275. if (ll <= mid) update_sum_point(l, mid, ll, x + x, y);
  276. else update_sum_point(mid + 1, r, ll, x + x + 1, y);
  277. if (t[x].mn == global_pos1) t[x].sum += y;
  278. return;
  279. }
  280.  
  281. void update_sum(int l, int r, int ll, int rr, int x, int y, int z) {
  282. if (l > r || ll > r || l > rr || ll > rr || t[x].mn > z) return;
  283. if (l >= ll && r <= rr) {
  284. if (t[x].mn != z) return;
  285. t[x].sum += (t[x].cnt_mn * 1ll * y);
  286. t[x].qsum += y;
  287. return;
  288. }
  289. int mid = (l + r) >> 1;
  290. push(x);
  291. update_sum(l, mid, ll, rr, x + x, y, z);
  292. update_sum(mid + 1, r, ll, rr, x + x + 1, y, z);
  293. update_NODE(x);
  294. return;
  295. }
  296.  
  297. void clr_node(int l, int r, int ll, int rr, int x, int y) {
  298. if (l > r || ll > r || l > rr || ll > rr || t[x].mn > y) return;
  299. if (l >= ll && r <= rr) {
  300. if (t[x].mn != y) return;
  301. t[x].ob = true;
  302. t[x].sum = t[x].qsum = 0;
  303. return;
  304. }
  305. int mid = (l + r) >> 1;
  306. push(x);
  307. clr_node(l, mid, ll, rr, x + x, y);
  308. clr_node(mid + 1, r, ll, rr, x + x + 1, y);
  309. update_NODE(x);
  310. return;
  311. }
  312.  
  313. ///////////////////////////// Answer Queries
  314.  
  315. long long get_point(int l, int r, int ll, int x) {
  316. int mid;
  317. while (l != r) {
  318. mid = (l + r) >> 1;
  319. push(x);
  320. if (ll <= mid) x <<= 1, r = mid;
  321. else x = x + x + 1, l = mid + 1;
  322. }
  323. return t[x].sum;
  324. }
  325.  
  326. int get_point_mn(int x) {
  327. x += sz - 1;
  328. int res = t[x].mn;
  329. x >>= 1;
  330. while (x) {
  331. res += t[x].qmn;
  332. x >>= 1;
  333. }
  334. return res;
  335. }
  336.  
  337.  
  338. long long get_sum(int l, int r, int ll, int rr, int x, int y) {
  339. if (l > r || ll > r || l > rr || ll > rr || t[x].mn > y) return 0;
  340. if (l >= ll && r <= rr) {
  341. if (t[x].mn != y) return 0;
  342. return t[x].sum;
  343. }
  344. int mid = (l + r) >> 1;
  345. push(x);
  346. return get_sum(l, mid, ll, rr, x + x, y) + get_sum(mid + 1, r, ll, rr, x + x + 1, y);
  347. }
  348.  
  349. long long query_4(int x) {
  350. return get_point(1, sz, tin[x], 1);
  351. }
  352.  
  353. long long query_5(int x) {
  354. x = get_last(1, sz, 1, tin[x], 1, tout[x]);
  355. if (!x) x = 1;
  356. x = poc[x];
  357. int y = get_point_mn(tin[x]);
  358. return get_sum(1, sz, tin[x], tout[x], 1, y);
  359. }
  360.  
  361. int query_7() {
  362. int x, y;
  363. x = FIR;
  364. if (x != 1e9) {
  365. y = SEC;
  366. x = poc[x];
  367. y = poc[y];
  368. return ((ans_query7 + get_number_of_edges(x, y, get_point_mn(tin[x]), get_point_mn(tin[y]))) >> 1);
  369. }
  370. return 0;
  371. }
  372.  
  373. ///////////////////////////////// Modify Queries
  374.  
  375.  
  376. void query_1(int r) {
  377. int x = ed[r].second;
  378. int xx = ed[r].first;
  379. xx = get_last(1, sz, 1, tin[xx], 1, tout[xx]);
  380. if (!xx) xx = 1;
  381. xx = poc[xx];
  382.  
  383. if (get_first_vertex(1, sz, tin[x], tout[x], 1)) {
  384. if (FIR < tin[x]) {
  385. if (bin_ed[r] == '0') ++ans_query7;
  386. else --ans_query7;
  387. }
  388. if (SEC > tout[x]) {
  389. if (bin_ed[r] == '0') ++ans_query7;
  390. else --ans_query7;
  391. }
  392. }
  393.  
  394. if (bin_ed[r] == '1') {
  395. update_edge(tin[x], 0);
  396. update_cnt(1, sz, tin[x], tout[x], 1, -1);
  397. bin_ed[r] = '0';
  398. } else {
  399. update_edge(tin[x], tout[x]);
  400. update_cnt(1, sz, tin[x], tout[x], 1, 1);
  401. bin_ed[r] = '1';
  402. }
  403.  
  404. if (bin_ed[r] == '0') {
  405. if (comp[x]) {
  406. update_component(x);
  407. if (!comp[xx]) update_component(xx);
  408. }
  409. } else if (comp[xx]) {
  410. if (is_there_somebody(x, 1)) {
  411. update_component(x);
  412. if (!is_there_somebody(xx, 1)) update_component(xx);
  413. }
  414. }
  415. return;
  416. }
  417.  
  418. void query_2(int x, int z) {
  419. x = get_last(1, sz, 1, tin[x], 1, tout[x]);
  420. if (!x) x = 1;
  421. x = poc[x];
  422. if (!comp[x]) update_component(x);
  423. int y = get_point_mn(tin[x]);
  424. update_sum(1, sz, tin[x], tout[x], 1, z, y);
  425. return;
  426. }
  427.  
  428. void query_6(int x) {
  429. x = get_last(1, sz, 1, tin[x], 1, tout[x]);
  430. if (!x) x = 1;
  431. x = poc[x];
  432. if (comp[x]) update_component(x);
  433. int y = get_point_mn(tin[x]);
  434. clr_node(1, sz, tin[x], tout[x], 1, y);
  435. return;
  436. }
  437.  
  438. void query_3(int x) {
  439. int y = x;
  440. x = get_last(1, sz, 1, tin[x], 1, tout[x]);
  441. if (!x) x = 1;
  442. x = poc[x];
  443. long long xx = query_5(x);
  444. clr_node(1, sz, tin[x], tout[x], 1, get_point_mn(tin[x]));
  445. update_sum_point(1, sz, tin[y], 1, xx);
  446. return;
  447. }
  448.  
  449. bool dfs_init(int x, int y, bool edge) {
  450. bool is_there = false;
  451. if (t[sz + tin[x] - 1].sum) is_there = true;
  452. for (int i = 0; i < v[x].size(); ++i) {
  453. int to = v[x][i].first;
  454. if (to == y) continue;
  455. if (bin_ed[v[x][i].second] == '1') {
  456. dfs_init(to, x, 1);
  457. } else {
  458. if (dfs_init(to, x, 0)) is_there = true;
  459. }
  460. }
  461. if (edge && is_there) {
  462. comp[x] = 1;
  463. vert_cnt[sz + tin[x] - 1] = 1;
  464. }
  465. return is_there;
  466. }
  467.  
  468. bool dfs_init2(int x, int y) {
  469. bool is_there = false;
  470. if (t[sz + tin[x] - 1].sum) is_there = true;
  471. for (int i = 0; i < v[x].size(); ++i) {
  472. int to = v[x][i].first;
  473. if (to == y) continue;
  474. if (bin_ed[v[x][i].second] == '1') {
  475. if (dfs_init2(to, x)) {
  476. is_there = true;
  477. ++ans_query7;
  478. }
  479. } else if (dfs_init2(to, x)) is_there = true;
  480. }
  481. return is_there;
  482. }
  483.  
  484. void dfs_init3(int x, int y, int _d, int l) {
  485. if (x == l) ans_query7 -= _d;
  486. for (int i = 0; i < v[x].size(); ++i) {
  487. int to = v[x][i].first;
  488. if (to != y) dfs_init3(to, x, _d + (bin_ed[v[x][i].second] - '0'), l);
  489. }
  490. return;
  491. }
  492.  
  493. ///////////////////////////////
  494.  
  495.  
  496.  
  497. void init(int N, vector<int> v, vector<int> u, vector<int> b, vector<int> a, int GROUP) {
  498. n = N;
  499. int x, y;
  500. for (int i = 1; i < n; ++i) {
  501. x = v[i - 1];
  502. y = u[i - 1];
  503. ed[i] = {x, y};
  504. ::v[x].push_back({y, i});
  505. ::v[y].push_back({x, i});
  506. }
  507. bin_ed = "#";
  508. for (int i = 0; i < b.size(); ++i)
  509. bin_ed += char(b[i] + '0');
  510. dfs(1, 0);
  511. build_sparse_table();
  512. for (int i = 1; i < n; ++i) {
  513. x = ed[i].first;
  514. y = ed[i].second;
  515. if (tin[y] < tin[x]) swap(ed[i].first, ed[i].second);
  516. }
  517. sz = 1;
  518. while (sz < n) sz += sz;
  519. for (int i = 1; i <= n; ++i)
  520. t[sz + i - 1].cnt_mn = 1;
  521. for (int i = sz - 1; i > 0; --i)
  522. t[i].cnt_mn = t[i + i].cnt_mn + t[i + i + 1].cnt_mn;
  523.  
  524. int rr;
  525. for (int i = 1; i < n; ++i)
  526. if (bin_ed[i] == '1') {
  527. rr = ed[i].second;
  528. max_tout[tin[rr] + sz - 1] = tout[rr];
  529. qob[tin[rr]]++;
  530. qob[tout[rr] + 1]--;
  531. }
  532. for (int i = 1; i <= n; ++i) {
  533. qob[i] += qob[i - 1];
  534. t[sz + tin[i] - 1].sum += a[i - 1];
  535. t[sz + i - 1].mn = qob[i];
  536. }
  537. for (int i = sz - 1; i > 0; --i) {
  538. max_tout[i] = max_tout[i + i];
  539. if (max_tout[i + i + 1] > max_tout[i]) max_tout[i] = max_tout[i + i + 1];
  540. update_NODE(i);
  541. }
  542.  
  543. dfs_init(1, 0, true);
  544. for (int i = sz - 1; i > 0; --i)
  545. vert_cnt[i] = vert_cnt[i + i] + vert_cnt[i + i + 1];
  546. /// ������¿������¾����¯�¿�½����¯�¿�½������¸����¯�¿�½������°����¯�¿�½����¯�¿�½ ������¾����¯�¿�½������²������µ����¯�¿�½
  547. int pos = 0;
  548. for (int i = 1; i <= n; ++i)
  549. if (comp[i]) {
  550. pos = i;
  551. break;
  552. }
  553. if (pos) {
  554. dfs_init2(pos, 0);
  555. ans_query7 *= 2;
  556. int fir = -1;
  557. int last = -1;
  558. for (int i = 1; i <= n; ++i)
  559. if (comp[poc[i]]) {
  560. if (fir == -1) fir = i;
  561. last = i;
  562. }
  563. FIR = fir;
  564. SEC = last;
  565. fir = poc[fir];
  566. last = poc[last];
  567. dfs_init3(fir, 0, 0, last);
  568. }
  569. return;
  570. }
  571.  
  572.  
  573. int main(int argc, const char * argv[]) {
  574. // ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  575. int x, y;
  576. cin >> group;
  577. cin >> n >> m;
  578. vector<int> vv, uu;
  579. for (int i = 1; i < n; ++i) {
  580. cin >> x >> y;
  581. vv.push_back(x);
  582. uu.push_back(y);
  583. }
  584. cin >> bin_ed;
  585. vector<int> b, a;
  586. for (int i = 0; i < (int)bin_ed.size(); ++i)
  587. b.push_back(bin_ed[i] - '0');
  588. for (int i = 1; i <= n; ++i) {
  589. cin >> x;
  590. a.push_back(x);
  591. }
  592. init(n, vv, uu, b, a, group);
  593. int tp;
  594. for (int it = 1; it <= m; ++it) {
  595. cin >> tp;
  596. if (tp == 1) {
  597. cin >> x;
  598. query_1(x);
  599. } else if (tp == 2) {
  600. cin >> x >> y;
  601. query_2(x, y);
  602. } else if (tp == 3) {
  603. cin >> x;
  604. query_3(x);
  605. } else if (tp == 4) {
  606. cin >> x;
  607. cout << query_4(x) << '\n';
  608. } else if (tp == 5) {
  609. cin >> x;
  610. cout << query_5(x) << '\n';
  611. } else if (tp == 6) {
  612. cin >> x;
  613. query_6(x);
  614. } else {
  615. cout << query_7() << '\n';
  616. }
  617. }
  618. return 0;
  619. }
  620.  
  621. ////
  622.  
Success #stdin #stdout 0s 105344KB
stdin
Standard input is empty
stdout
Standard output is empty