제출 #1176616

#제출 시각아이디문제언어결과실행 시간메모리
1176616MercubytheFirstSprinkler (JOI22_sprinkler)C++20
53 / 100
4094 ms53120 KiB
#pragma GCC optimize("O3","unroll-loops","-fexpensive-optimizations","-finline","-finline-small-functions","-ffast-math") #include "bits/stdc++.h" using namespace std; using ll = long long; #ifdef LOCAL #include "debug.h" mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); #else #define debug(...) 42 mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); #endif int mod = 0; struct SegmentTree { int n; vector<ll> t; SegmentTree() { } SegmentTree(int sz, const vector<int>& a) : n(sz), t(2*n) { for(int i = 0; i < n; ++i) { t[i+n] = a[i]; } for(int i = n-1; i >= 1; --i) { t[i] = 1; } } inline void update(int l, int r, int m) { for(l += n, r += n; l <= r; l /= 2, r /= 2) { if(l % 2 == 1) { t[l] = t[l] * m % mod; l++; } if(r % 2 == 0) { t[r] = t[r] * m % mod; r--; } } } inline int query(int idx) { ll ans = 1; for(idx += n; idx >= 1; idx /= 2) { ans = ans * t[idx] % mod; } return ans; } }; inline void solve() { int n; cin >> n >> mod; vector<vector<int>> g(n + 1); for(int i = 1; i < n; ++i) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } vector<int> a(n+1); for(int i = 1; i <= n; ++i) { cin >> a[i]; } int timer = 0; int max_dep = 0; vector<int> tin(n+1), tout(n+1), dep(n+1), ett, par(n+1); vector<vector<int>> depg(n+1); auto pre_dfs = [&](auto&& dfs, int v, int p) -> void { ett.push_back(v); tin[v] = tout[v] = timer++; depg[dep[v]].push_back(tin[v]); max_dep = max(max_dep, dep[v]); for(int to : g[v]) { if(to == p) { continue; } par[to] = v; dep[to] = dep[v] + 1; dfs(dfs, to, v); tout[v] = max(tout[v], tout[to]); } }; pre_dfs(pre_dfs, 1, 0); vector<SegmentTree> trees(n+1); for(int i = 0; i <= max_dep; ++i) { vector<int> cura; for(int x : depg[i]) { cura.push_back(a[ett[x]]); } trees[i] = SegmentTree(size(cura), cura); } int Q; cin >> Q; auto update = [&](int tlb, int trb, int tar_d, int val) -> void { if(tar_d > max_dep) { return; } const int lb = lower_bound(begin(depg[tar_d]), end(depg[tar_d]), tlb) - begin(depg[tar_d]); const int rb = upper_bound(begin(depg[tar_d]), end(depg[tar_d]), trb) - begin(depg[tar_d]) - 1; trees[tar_d].update(lb, rb, val); }; while(Q--) { int qt; cin >> qt; if(qt == 1) { int node, dist, val; cin >> node >> dist >> val; int head = node; int go_down = dist; for(int i = dist; i >= 0; --i) { if(go_down < 0) { break; } debug(head, dep[head]+go_down); update(tin[head], tout[head], dep[head] + go_down, val); if(go_down == 0) { break; } update(tin[head], tout[head], dep[head] + go_down - 1, val); if(par[head]) { head = par[head]; go_down--; } else { go_down -= 2; } } } else { int x; cin >> x; const int idx = lower_bound(begin(depg[dep[x]]), end(depg[dep[x]]), tin[x]) - begin(depg[dep[x]]); cout << trees[dep[x]].query(idx) << '\n'; } } } signed main(){ #ifdef LOCAL freopen("test.in", "r", stdin); freopen("test.err", "w", stderr); #endif ios_base::sync_with_stdio(false); cin.tie(NULL); signed T = 1; // cin >> T; for(signed test = 1; test <= T; ++test){ solve(); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...