Advertisement
Guest User

hld

a guest
Jun 20th, 2020
1,861
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.70 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <chrono>
  3.  
  4. using namespace std;
  5. using namespace std::chrono;
  6.  
  7. // #pragma GCC target ("avx2")
  8. // #pragma GCC optimization ("O3")
  9. // #pragma GCC optimization ("unroll-loops")
  10. // #pragma optimization_level 3
  11. // #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
  12. // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  13.  
  14. #define f0r(a, b) for (long long a = 0; a < (b); ++a)
  15. #define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
  16. #define f0rd(a, b) for (long long a = (b); a >= 0; --a)
  17. #define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
  18. #define ms(arr, v) memset(arr, v, sizeof(arr))
  19. #define pb push_back
  20. #define send {ios_base::sync_with_stdio(false);}
  21. #define help {cin.tie(NULL); cout.tie(NULL);}
  22. #define fix(prec) {cout << setprecision(prec) << fixed;}
  23. #define mp make_pair
  24. #define f first
  25. #define s second
  26. #define all(v) v.begin(), v.end()
  27. #define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
  28. #define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
  29. #define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
  30. #define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
  31. #define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
  32. #define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
  33. #define vsz(x) ((long long) x.size())
  34. typedef long long ll;
  35. typedef double ld;
  36. typedef long double lld;
  37. typedef unsigned long long ull;
  38. typedef pair<int, int> pii;
  39. typedef pair<ll, ll> pll;
  40. typedef vector<int> vi;
  41. typedef vector<ll> vl;
  42. typedef vector<pii> vpi;
  43. typedef vector<pll> vpl;
  44.  
  45. template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
  46. template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
  47. template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  48. cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
  49. }
  50. template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  51. cin >> p.first;
  52. return cin >> p.second;
  53. }
  54.  
  55. // mt19937 rng(steady_clock::now().time_since_epoch().count());
  56. mt19937 rng(61378913);
  57. /* usage - just do rng() */
  58.  
  59. void usaco(string filename) {
  60. // #pragma message("be careful, freopen may be wrong")
  61. freopen((filename + ".in").c_str(), "r", stdin);
  62. freopen((filename + ".out").c_str(), "w", stdout);
  63. }
  64.  
  65. const lld pi = 3.14159265358979323846;
  66. // const ll mod = 1000000007;
  67. // const ll mod = 998244353;
  68. // ll mod;
  69.  
  70.  
  71.  
  72. ll n, m, k, q, l, r, x, y, z;
  73. ll a[1000005];
  74. ll b[1000005];
  75. ll c[1000005];
  76. string s, t;
  77. ll ans = 0;
  78.  
  79. template<int size, int lg, typename seg_t = long long>
  80. struct hld {
  81. vector<int> edges[size];
  82. int bigchild[size];
  83. int sz[size];
  84. int depth[size];
  85. int chain[size];
  86. int label[size], label_time;
  87. int par[size];
  88.  
  89. int lca_lift[size][lg];
  90.  
  91. seg_t seg_tree[4 * size];
  92. seg_t seg_lazy[4 * size];
  93.  
  94. int N;
  95.  
  96. /* ----------- segment tree ----------- */
  97.  
  98. /* CHANGE THIS SECTION BY PROBLEM */
  99. inline seg_t seg_combine(seg_t a, seg_t b) {
  100. return a ^ b;
  101. }
  102.  
  103. inline seg_t seg_lazy_apply(seg_t lazy_val, seg_t new_val) {
  104. return new_val;
  105. }
  106.  
  107. inline seg_t seg_lazy_func(seg_t cur_val, seg_t lazy_val, int l, int r) {
  108. return lazy_val;
  109. }
  110.  
  111. const seg_t seg_sentinel = 0;
  112. const seg_t seg_lazy_sentinel = -1;
  113. const seg_t seg_init_val = 0;
  114. /* END SECTION */
  115.  
  116. seg_t seg_query_header(int l, int r) {
  117. return seg_query_rec(0, 0, N - 1, l, r);
  118. }
  119.  
  120. seg_t seg_query_rec(int i, int tl, int tr, int ql, int qr) {
  121. seg_eval_lazy(i, tl, tr);
  122.  
  123. if (ql <= tl && tr <= qr) return seg_tree[i];
  124. if (tl > tr || tr < ql || qr < tl) return seg_sentinel;
  125.  
  126. int mid = (tl + tr) / 2;
  127. seg_t a = seg_query_rec(2 * i + 1, tl, mid, ql, qr);
  128. seg_t b = seg_query_rec(2 * i + 2, mid + 1, tr, ql, qr);
  129. return seg_combine(a, b);
  130. }
  131.  
  132. void seg_update_header(int l, int r, seg_t v) {
  133. seg_update_rec(0, 0, N - 1, l, r, v);
  134. }
  135.  
  136. seg_t seg_update_rec(int i, int tl, int tr, int ql, int qr, seg_t v) {
  137. seg_eval_lazy(i, tl, tr);
  138.  
  139. if (tl > tr || tr < ql || qr < tl) return seg_tree[i];
  140. if (ql <= tl && tr <= qr) {
  141. seg_lazy[i] = seg_lazy_apply(seg_lazy[i], v);
  142. seg_eval_lazy(i, tl, tr);
  143. return seg_tree[i];
  144. }
  145. if (tl == tr) return seg_tree[i];
  146.  
  147. int mid = (tl + tr) / 2;
  148. seg_t a = seg_update_rec(2 * i + 1, tl, mid, ql, qr, v);
  149. seg_t b = seg_update_rec(2 * i + 2, mid + 1, tr, ql, qr, v);
  150. return seg_tree[i] = seg_combine(a, b);
  151. }
  152.  
  153. void seg_eval_lazy(int i, int l, int r) {
  154. if (seg_lazy[i] == seg_lazy_sentinel) return;
  155.  
  156. seg_tree[i] = seg_lazy_func(seg_tree[i], seg_lazy[i], l, r);
  157.  
  158. if (l != r) {
  159. seg_lazy[i * 2 + 1] = seg_lazy_apply(seg_lazy[i * 2 + 1], seg_lazy[i]);
  160. seg_lazy[i * 2 + 2] = seg_lazy_apply(seg_lazy[i * 2 + 2], seg_lazy[i]);
  161. }
  162.  
  163. seg_lazy[i] = seg_lazy_sentinel;
  164. }
  165.  
  166. /* ----------- init phase 1 ----------- */
  167. /* initialize segtree, clear edges, etc. */
  168.  
  169. void init_arrays(int n) {
  170. // everything not initialized doesn't need to be
  171. N = n;
  172. for (int i = 0; i < N; i++) {
  173. edges[i].clear();
  174. chain[i] = i;
  175. }
  176.  
  177. for (int i = 0; i < 4 * N; i++) {
  178. seg_tree[i] = seg_init_val;
  179. seg_lazy[i] = seg_lazy_sentinel;
  180. }
  181. }
  182.  
  183. /* ----------- init phase 2 ----------- */
  184. /* put edges in */
  185.  
  186. void add_edge(int u, int v) {
  187. edges[u].push_back(v);
  188. edges[v].push_back(u);
  189. }
  190.  
  191. /* ----------- init phase 3 ----------- */
  192. /* build the lca and hld stuff */
  193.  
  194. void init_tree(seg_t* arr, int root = 0) {
  195. // lca
  196. lca_dfs(root, -1);
  197.  
  198. // size, compute biggest children
  199. dfs_size(root, -1, 0);
  200.  
  201. // compute chains
  202. dfs_chains(root, -1);
  203.  
  204. // label nodes
  205. label_time = 0;
  206. dfs_labels(arr, root, -1);
  207. }
  208.  
  209. void lca_dfs(int v, int par) {
  210. lca_lift[v][0] = par;
  211.  
  212. for (int i = 1; i < lg; i++) {
  213. if (lca_lift[v][i - 1] == -1) lca_lift[v][i] = -1;
  214. else lca_lift[v][i] = lca_lift[lca_lift[v][i - 1]][i - 1];
  215. }
  216.  
  217. for (int x: edges[v]) {
  218. if (x != par) {
  219. lca_dfs(x, v);
  220. }
  221. }
  222. }
  223.  
  224. void dfs_size(int v, int p, int d) {
  225. sz[v] = 1;
  226. depth[v] = d;
  227. par[v] = p;
  228. int bigc = -1, bigv = -1;
  229.  
  230. for (int x: edges[v]) {
  231. if (x != p) {
  232. dfs_size(x, v, d + 1);
  233. sz[v] += sz[x];
  234. if (sz[x] > bigv) {
  235. bigc = x;
  236. bigv = sz[x];
  237. }
  238. }
  239. }
  240.  
  241. bigchild[v] = bigc;
  242. }
  243.  
  244. void dfs_chains(int v, int p) {
  245. if (bigchild[v] != -1) {
  246. chain[bigchild[v]] = chain[v];
  247. }
  248.  
  249. for (int x: edges[v]) {
  250. if (x != p) {
  251. dfs_chains(x, v);
  252. }
  253. }
  254. }
  255.  
  256. void dfs_labels(seg_t* arr, int v, int p) {
  257. label[v] = label_time++;
  258. seg_update_header(label[v], label[v], arr[v]);
  259.  
  260. if (bigchild[v] != -1) {
  261. dfs_labels(arr, bigchild[v], v);
  262. }
  263.  
  264. for (int x: edges[v]) {
  265. if (x != p && x != bigchild[v]) {
  266. dfs_labels(arr, x, v);
  267. }
  268. }
  269. }
  270.  
  271. /* ----------- init phase 4 ----------- */
  272. /* usage */
  273.  
  274. int lca(int a, int b) {
  275. if (depth[a] < depth[b]) swap(a, b);
  276. int d = depth[a] - depth[b];
  277. int v = get_kth_ancestor(a, d);
  278. if (v == b) {
  279. return v;
  280. } else {
  281. for (int i = lg - 1; i >= 0; i--) {
  282. if (lca_lift[v][i] != lca_lift[b][i]) {
  283. v = lca_lift[v][i];
  284. b = lca_lift[b][i];
  285. }
  286. }
  287. return lca_lift[b][0];
  288. }
  289. }
  290.  
  291. int get_kth_ancestor(int v, int k) {
  292. for (int i = lg - 1; i >= 0; i--) {
  293. if (v == -1) return v;
  294. if ((1 << i) <= k) {
  295. v = lca_lift[v][i];
  296. k -= (1 << i);
  297. }
  298. }
  299. return v;
  300. }
  301.  
  302. /* excludes p */
  303. seg_t query_chain(int v, int p) {
  304. seg_t val = seg_sentinel;
  305. while (depth[p] < depth[v]) {
  306. int top = chain[v];
  307. if (depth[top] <= depth[p]) {
  308. int diff = depth[v] - depth[p];
  309. top = get_kth_ancestor(v, diff - 1);
  310. }
  311. val = seg_combine(val, seg_query_header(label[top], label[v]));
  312. v = par[top];
  313. }
  314. return val;
  315. }
  316.  
  317. seg_t query(int u, int v) {
  318. int lc = lca(u, v);
  319. seg_t val = seg_combine(query_chain(u, lc), query_chain(v, lc));
  320. return seg_combine(val, seg_query_header(label[lc], label[lc]));
  321. }
  322.  
  323. /* excludes p */
  324. void update_chain(int v, int p, seg_t val) {
  325. while (depth[p] < depth[v]) {
  326. int top = chain[v];
  327. if (depth[top] <= depth[p]) {
  328. int diff = depth[v] - depth[p];
  329. top = get_kth_ancestor(v, diff - 1);
  330. }
  331. seg_update_header(label[top], label[v], val);
  332. v = par[top];
  333. }
  334. }
  335.  
  336. void update(int u, int v, seg_t val) {
  337. int lc = lca(u, v);
  338. update_chain(u, lc, val);
  339. update_chain(v, lc, val);
  340. seg_update_header(label[lc], label[lc], val);
  341. }
  342. };
  343.  
  344. hld<100005, 20, ll> h;
  345.  
  346. void solve(int tc) {
  347. cin >> n >> q;
  348.  
  349. ai(a, n);
  350.  
  351. h.init_arrays(n);
  352.  
  353. f0r(i, n - 1) {
  354. cin >> x >> y; --x; --y;
  355. h.add_edge(x, y);
  356. }
  357.  
  358. h.init_tree(a);
  359.  
  360. f0r(i, q) {
  361. int t; cin >> t;
  362. if (t == 1) {
  363. int v; cin >> x >> v; --x;
  364. h.update(x, x, v);
  365. } else {
  366. cin >> x >> y; --x; --y;
  367. cout << h.query(x, y) << '\n';
  368. }
  369. }
  370. }
  371.  
  372. int main() {
  373. send help
  374.  
  375. usaco("cowland");
  376.  
  377. int tc = 1;
  378. // cin >> tc;
  379. for (int t = 0; t < tc; t++) solve(t);
  380. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement