Submission #850819

#TimeUsernameProblemLanguageResultExecution timeMemory
850819EJIC_B_KEDAXSprinkler (JOI22_sprinkler)C++14
41 / 100
4046 ms141784 KiB
#include <bits/stdc++.h> #include <random> #ifndef LOCAL #pragma GCC optimize("O3") #pragma GCC optimize("Ofast") //#pragma GCC optimize("unroll-loops") #pragma GCC target("avx,avx2,bmi,bmi2,popcnt,lzcnt") #endif using namespace std; typedef long long ll; typedef double dd; typedef long double ld; typedef unsigned int uii; #define x first #define y second #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() void solve(); mt19937_64 mt(1); int32_t main() { #ifdef LOCAL freopen("input.in", "r", stdin); freopen("output.out", "w", stdout); #else ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen("amusing.in", "r", stdin); //freopen("amusing.out", "w", stdout); #endif cout << fixed << setprecision(30); int tests = 1; //cin >> tests; while (tests--) { solve(); } } ll mod; class SegmentTree { public: void build(const vector<int>& b) { int sz = 1; while (sz < b.size()) { sz *= 2; } x.resize(2 * sz - 1); vn.resize(2 * sz - 1, 1); size = 2 * sz - 1; for (int i = sz - 1; i < 2 * sz - 1; i++) { if (i - sz + 1 < b.size()) { x[i] = b[i - sz + 1]; } else { x[i] = 0; } } for (int i = sz - 2; i >= 0; i--) { //update(i); x[i] = 0; } } int get(int l, int r, int i = 0, int lx = 0, int rx = -1) { if (rx == -1) { rx = size / 2; } if (lx > r || rx < l) { return 0; } if (lx >= l && rx <= r) { return x[i]; } updateVN(i); return get(l, r, 2 * i + 1, lx, (rx + lx) / 2) + get(l, r, 2 * i + 2, (rx + lx) / 2 + 1, rx); } void change(int ind, int c, int i = 0, int lx = 0, int rx = -1) { if (rx == -1) { rx = size / 2; } if (lx == rx) { x[i] = c; return; } updateVN(i); if ((rx + lx) / 2 >= ind) { change(ind, c, 2 * i + 1, lx, (rx + lx) / 2); } else { change(ind, c, 2 * i + 2, (rx + lx) / 2 + 1, rx); } //update(i); } void plusOtr(int l, int r, ll p, int i = 0, int lx = 0, int rx = -1) { if (r < l) { return; } if (rx == -1) { rx = size / 2; } if (lx >= l && rx <= r) { x[i] = (x[i] * p) % mod; vn[i] = (vn[i] * p) % mod; return; } if (lx > r || rx < l) { return; } updateVN(i); plusOtr(l, r, p, 2 * i + 1, lx, (rx + lx) / 2); plusOtr(l, r, p, 2 * i + 2, (rx + lx) / 2 + 1, rx); //update(i); } private: vector<ll> x, vn; int size; void updateVN(int i) { if (2 * i + 2 < size) { if (vn[i] != 1) { if (x[2 * i + 1]) { x[2 * i + 1] = (x[2 * i + 1] * vn[i]) % mod; } vn[2 * i + 1] = (vn[2 * i + 1] * vn[i]) % mod; if (x[2 * i + 2]) { x[2 * i + 2] = (x[2 * i + 2] * vn[i]) % mod; } vn[2 * i + 2] = (vn[2 * i + 2] * vn[i]) % mod; vn[i] = 1; } } } void update(int i) { if (2 * i + 2 < size) { x[i] = x[2 * i + 1] + x[2 * i + 2]; } } }; pair<int, int> seg[200200][41]; void dfs(int s, int p, vector<vector<int>>& g, int dist[], vector<vector<int>>& d, int pr[]) { if (p != -1) { dist[s] = dist[p] + 1; } else { dist[s] = 0; } pr[s] = p; d[dist[s]].push_back(s); seg[s][0] = {d[dist[s]].size() - 1, d[dist[s]].size() - 1}; for (int i = 1; i < 41; i++) { seg[s][i] = {INT32_MAX, INT32_MIN}; } bool f = true; for (int i : g[s]) { if (i != p) { dfs(i, s, g, dist, d, pr); for (int j = 1; j < 41; j++) { seg[s][j].x = min(seg[s][j].x, seg[i][j - 1].x); } for (int j = 1; j < 41; j++) { seg[s][j].y = max(seg[s][j].y, seg[i][j - 1].y); } } } } void solve() { int n; cin >> n >> mod; vector<vector<int>> g(n), d(n); int deg[200200], dist[200200], h[200200], p[200200]; for (int i = 0; i < n; i++) { deg[i] = 0; } for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; u--; v--; g[u].push_back(v); g[v].push_back(u); deg[u]++; deg[v]++; } int root = 0; for (int i = 0; i < n; i++) { if (deg[i] == 1) { root = i; break; } } dfs(root, -1, g, dist, d, p); for (int i = 0; i < n; i++) { cin >> h[i]; } for (int i = 0; i < n; i++) { for (int j = 0; j < d[i].size(); j++) { d[i][j] = h[d[i][j]]; } } SegmentTree dec[200200]; for (int i = 0; i < n; i++) { dec[i].build(d[i]); } int q; cin >> q; while (q--) { int t; cin >> t; if (t == 1) { int x, dk, wk; cin >> x >> dk >> wk; x--; int nw = x, lev = 0, nlev = 0; for (int l = -dk; l <= dk; l++) { if (dist[x] - l < 0) { break; } if (dist[x] - l >= n) { continue; } int c = (dk + l) / 2; while (c > nlev) { nlev++; if (p[nw] != -1) { lev++; nw = p[nw]; } } if (c - l >= 0 && c - l <= dk) { int l1, r1; l1 = seg[nw][lev - l].x; r1 = seg[nw][lev - l].y; dec[dist[x] - l].plusOtr(l1, r1, wk); } } } else { int x; cin >> x; x--; cout << (dec[dist[x]].get(seg[x][0].x, seg[x][0].y) % mod + mod) % mod << '\n'; } } }

Compilation message (stderr)

sprinkler.cpp: In member function 'void SegmentTree::build(const std::vector<int>&)':
sprinkler.cpp:50:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   50 |         while (sz < b.size()) {
      |                ~~~^~~~~~~~~~
sprinkler.cpp:57:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   57 |             if (i - sz + 1 < b.size()) {
      |                 ~~~~~~~~~~~^~~~~~~~~~
sprinkler.cpp: In function 'void dfs(int, int, std::vector<std::vector<int> >&, int*, std::vector<std::vector<int> >&, int*)':
sprinkler.cpp:160:10: warning: unused variable 'f' [-Wunused-variable]
  160 |     bool f = true;
      |          ^
sprinkler.cpp: In function 'void solve()':
sprinkler.cpp:202:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  202 |         for (int j = 0; j < d[i].size(); j++) {
      |                         ~~^~~~~~~~~~~~~
#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...