Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
//Слава Україні, Героям слава #include
using namespace std; struct seg_tree { //modify accordingly int n; vector
v, lz, st; void build() { build(1, 1, n); } void build(int p, int l, int r) { if(l == r) { st[p] = v[l]; return; } build(2 * p, l, (l + r) >> 1); build(2 * p + 1, ((l + r) >> 1) + 1, r); st[p] = st[2 * p] + st[2 * p + 1]; } seg_tree(int n_ = 1) { n = n_; lz.resize(4 * n); st.resize(4 * n); v.resize(n + 1); build(); } seg_tree(vector
&v_) { v = v_; n = v.size(); n--; lz.resize(4 * n); st.resize(4 * n); build(); } void push(int p, int l, int r) { if(lz[p]) { st[p] = (r - l + 1) * lz[p]; if(l != r) { lz[2 * p] = lz[p]; lz[2 * p + 1] = lz[p]; } lz[p] = 0; } } unsigned long long query(int i, int j) { return query(i, j, 1, 1, n); } unsigned long long query(int i, int j, int p, int l, int r) { push(p, l, r); if(l > j or r < i) { return 0; } if(l >= i and j >= r) { return st[p]; } return query(i, j, 2 * p, l, (l + r) >> 1) + query(i, j, 2 * p + 1, ((l + r) >> 1) + 1, r); } void update(int i, int j, unsigned long long v) { update(i, j, v, 1, 1, n); } void update(int i, int j, unsigned long long v, int p, int l, int r) { push(p, l, r); if(l > j or r < i) { return; } if(l >= i and j >= r) { lz[p] = v; push(p, l, r); return; } update(i, j, v, 2 * p, l, (l + r) >> 1); update(i, j, v, 2 * p + 1, ((l + r) >> 1) + 1, r); st[p] = st[2 * p] + st[2 * p + 1]; } }; template
struct HLD { vector
> g1; vector
>> g2; vector
pos, sz, par, h; vector
v, w, sobe; seg_tree seg; int t; HLD(int n) { if(EDGE) { g2.resize(n + 3); } else { g1.resize(n + 3); } pos.resize(n + 3); sz.resize(n + 3); par.resize(n + 3); if(EDGE) { sobe.resize(n + 3); } else { w.resize(n + 3); } h.resize(n + 3); v.resize(n + 3); } void build_hld(int k, int p = -1, int f = 1) { v[pos[k] = t++] = (EDGE ? sobe : w)[k]; sz[k] = 1; for(int i = 0; i < (int)(EDGE ? g2[k].size() : g1[k].size()); i++) { if((EDGE and g2[k][i].first != p) or (!EDGE and g1[k][i] != p)) { if(EDGE) { sobe[g2[k][i].first] = g2[k][i].second; par[g2[k][i].first] = k; h[g2[k][i].first] = (g2[k][i] == g2[k][0] ? h[k] : g2[k][i].first); build_hld(g2[k][i].first, k, f); sz[k] += sz[g2[k][i].first]; if(sz[g2[k][i].first] > sz[g2[k][0].first] or g2[k][0].first == p) { swap(g2[k][i], g2[k][0]); } } else { par[g1[k][i]] = k; h[g1[k][i]] = (g1[k][i] == g1[k][0] ? h[k] : g1[k][i]); build_hld(g1[k][i], k, f); sz[k] += sz[g1[k][i]]; if(sz[g1[k][i]] > sz[g1[k][0]] or g1[k][0] == p) { swap(g1[k][i], g1[k][0]); } } } } if(p * f == -1) { t = 1; build_hld(h[k] = k, -1, 0); } } void add(int a, int b) { g1[a].push_back(b); g1[b].push_back(a); } void add(int a, int b, int x) { g2[a].push_back({b, x}); g2[b].push_back({a, x}); } void build(int root = 1) { t = 1; build_hld(root); seg = seg_tree(v); } unsigned long long query_path(int a, int b) { if(EDGE and a == b) return 0; if(pos[a] < pos[b]) swap(a, b); if(h[a] == h[b]) return seg.query(pos[b] + EDGE, pos[a]); return seg.query(pos[h[a]], pos[a]) + query_path(par[h[a]], b); } void update_path(int a, int b, unsigned long long x) { if(EDGE and a == b) return; if(pos[a] < pos[b]) swap(a, b); if(h[a] == h[b]) { seg.update(pos[b] + EDGE, pos[a], x); return; } seg.update(pos[h[a]], pos[a], x); update_path(par[h[a]], b, x); } unsigned long query_subtree(int a) { if(EDGE and sz[a] == 1) return 0; return seg.query(pos[a] + EDGE, pos[a] + sz[a] - 1); } void update_subtree(int a, int x) { if(EDGE and sz[a] == 1) return; seg.update(pos[a] + EDGE, pos[a] + sz[a] - 1, x); } }; using ull = unsigned long long; random_device rd; mt19937 gen(rd()); uniform_int_distribution
distrib(0, ULLONG_MAX); int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while(t--) { int n, q; cin >> n >> q; vector
v(n + 3); vector
hsh(n + 1), perm(n + 1); set
st; for(int i = 1; i <= n; i++) { cin >> v[i]; hsh[i] = distrib(gen); perm[i] = perm[i - 1] + hsh[i]; st.insert(perm[i]); } HLD
hld(n); for(int i = 1; i <= n; i++) hld.w[i] = hsh[v[i]]; for(int i = 1; i < n; i++) { int a, b; cin >> a >> b; hld.add(a, b); } hld.build(); while(q--) { int t, a, b; cin >> t >> a >> b; if(t == 1) { unsigned long long x = hld.query_path(a, b); cout << (st.find(x) != st.end() ? "Yes\n" : "No\n"); } else { hld.update_path(a, a, hsh[b]); } } } return 0; }
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)