제출 #875809

#제출 시각아이디문제언어결과실행 시간메모리
875809danikoynovSprinkler (JOI22_sprinkler)C++14
100 / 100
623 ms157168 KiB
#include<bits/stdc++.h> #define endl '\n' using namespace std; typedef long long ll; void speed() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); } const int maxq = 4e5 + 10; struct query { int type, ver, d, t; ll w; }ask[maxq]; const int maxn = 2e5 + 10; int n, q; ll l, h[maxn]; vector < query > task[maxn]; vector < int > adj[maxn]; bool cmp(query a1, query a2) { return a1.d < a2.d; } void input() { cin >> n >> l; for (int i = 1; i < n; i ++) { int v, u; cin >> v >> u; adj[v].push_back(u); adj[u].push_back(v); } for (int i = 1; i <= n; i ++) cin >> h[i]; cin >> q; for (int i = 1; i <= q; i ++) { cin >> ask[i].type; if (ask[i].type == 1) cin >> ask[i].ver >> ask[i].d >> ask[i].w; else cin >> ask[i].ver; ask[i].t = i; } } struct segment_tree { vector < ll > tree, lazy; segment_tree(int len = 0) { tree.resize(4 * (len + 1)); lazy.resize(4 * (len + 1)); fill(tree.begin(), tree.end(), 1); fill(lazy.begin(), lazy.end(), 1); } void push_lazy(int &root, int &left, int &right) { tree[root] *= lazy[root]; tree[root] %= l; if (left != right) { lazy[root * 2] *= (lazy[root]); lazy[root * 2 + 1] *= (lazy[root]); lazy[root * 2] %= l; lazy[root * 2 + 1] %= l; } lazy[root] = 1; } void update_range(int root, int left, int right, int qleft, int qright, ll val) { if (tree[root] == 0) return; if (lazy[root] != 1) push_lazy(root, left, right); if (left > qright || right < qleft) return; if (left >= qleft && right <= qright) { lazy[root] = val; push_lazy(root, left, right); return; } int mid = (left + right) / 2; update_range(root * 2, left, mid, qleft, qright, val); update_range(root * 2 + 1, mid + 1, right, qleft, qright, val); } ll get_point(int root, int left, int right, int pos) { if (lazy[root] != 1) push_lazy(root, left, right); if (left == right) return tree[root]; int mid = (left + right) / 2; if (pos <= mid) return get_point(root * 2, left, mid, pos); return get_point(root * 2 + 1, mid + 1, right, pos); } }; const int maxd = 40; segment_tree st[maxn]; ll to_mult[maxn][maxd + 1]; int par[maxn], depth[maxn]; vector < int > by_depth[maxn]; int tin[maxn], tout[maxn], timer, rev[maxn]; void dfs(int v) { tin[v] = ++ timer; ///cout << "dfs " << v << " " << depth[v] << endl; rev[v] = by_depth[depth[v]].size(); by_depth[depth[v]].push_back(v); for (int u : adj[v]) { if (u == par[v]) continue; par[u] = v; depth[u] = depth[v] + 1; dfs(u); } tout[v] = timer; } void update_row(int row, int left, int right, ll val) { int lf = 0, rf = (int)(by_depth[row].size()) - 1; while(lf <= rf) { int mf = (lf + rf) / 2; if (tin[by_depth[row][mf]] < left) lf = mf + 1; else rf = mf - 1; } int lb = lf; lf = 0; rf = (int)(by_depth[row].size()) - 1; while(lf <= rf) { int mf = (lf + rf) / 2; if (tin[by_depth[row][mf]] <= right) lf = mf + 1; else rf = mf - 1; } int rb = rf; st[row].update_range(1, 0, (int)(by_depth[row].size()) - 1, lb, rb, val); } void make_query(int v) { ll ans = h[v]; int u = v, cnt = 0; while(u != 0 && cnt <= maxd) { ///cout << "query " << v << " " << u << " " << cnt << " " << to_mult[u][cnt] << endl; ans = ans * to_mult[u][cnt]; ans %= l; u = par[u]; cnt ++; } cout << ans << endl; } void simulate() { for (int i = 1; i <= n; i ++) { //st[i] = segment_tree(by_depth[i].size()); for (int j = 0; j <= maxd; j ++) to_mult[i][j] = 1; } for (int i = 1; i <= q; i ++) { if (ask[i].type == 2) make_query(ask[i].ver); else { int cnt = 0, ver = ask[i].ver; while(ver != 1 && cnt <= ask[i].d) { int lf = ask[i].d - cnt; to_mult[ver][lf] *= ask[i].w; if (lf != 0) to_mult[ver][lf - 1] *= ask[i].w; to_mult[ver][lf] %= l; if (lf != 0) to_mult[ver][lf - 1] %= l; ///update_row(depth[ver] + lf, tin[ver], tout[ver], ask[i].w); ///cout << "update " << ver << " " << depth[ver] + lf << endl; //if (lf != 0) ///update_row(depth[ver] + lf - 1, tin[ver], tout[ver], ask[i].w); cnt ++; ver = par[ver]; } if (ver == 1 && cnt <= ask[i].d) { int lf = ask[i].d - cnt; for (int j = 0; j <= lf; j ++) { ///cout << "update " << ver << " " << depth[ver] + j << endl; //update_row(depth[ver] + j, tin[ver], tout[ver], ask[i].w); to_mult[ver][j] *= ask[i].w; to_mult[ver][j] %= l; } } } } } void solve() { input(); ///offline_queries(); depth[1] = 1; dfs(1); simulate(); } int main() { speed(); solve(); return 0; }
#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...