Submission #1049571

#TimeUsernameProblemLanguageResultExecution timeMemory
10495710npataSprinkler (JOI22_sprinkler)C++17
3 / 100
4085 ms313072 KiB
#include<bits/stdc++.h> using namespace std; #define int long long #define vec vector #define hmap unordered_map const int MXN = 200'005; int N, L; int H[MXN]; bool is_centr[MXN*3]; vec<int> tree[MXN*3]; set<int> tree_i[MXN*3]; int fi = MXN; bool wn[MXN*3]; hmap<int, int> cache; int centr_dists[MXN*3][28]; int centr_subtree_inds[MXN*3][28]; const int weight(int u, int v) { if(u>v) swap(u, v); if(v < MXN) return 1; if(u >= MXN) return 0; return wn[v]; } class FenwickTree { public: int n; FenwickTree(int size) : n(size), tree(size + 1, 1) {} void upd(int32_t index, int value) { index = n-index; while (index <= n) { tree[index] = (tree[index] * value) % L; index += index & -index; } } int query_suffix(int32_t index) { index = n-index; int result = 1; while (index > 0) { result = (tree[index] * result) % L; index -= index & -index; } return result; } std::vector<int> tree; }; struct Centroid { vec<FenwickTree> subtree_contrs{}; int root; int size; FenwickTree contr; int mxd = 0; int layer; Centroid() : contr(1) {} Centroid(int root, int size, int layer) : root(root), size(size), contr(size+1), layer(layer) { is_centr[root] = true; centr_subtree_inds[root][layer] = -1; if(root < N) contr.upd(0, {H[root]}); centr_dists[root][layer] = 0; int si = 0; for(int u : tree[root]) { if(is_centr[u]) continue; dfs_init(u, root, weight(u, root), si++); } for(int i = 0; i<si; i++) { subtree_contrs.push_back(FenwickTree(mxd+1)); } } void dfs_init(int u, int p, int d, int s_i) { if(is_centr[u]) return; centr_subtree_inds[u][layer] = s_i; centr_dists[u][layer] = d; mxd = max(mxd, d); for(int v : tree[u]) { if(v == p) continue; dfs_init(v, u, d+weight(v, u), s_i); } } }; Centroid centroids[MXN*3]; int centroid_pars[MXN*3]; int subtree_sz[MXN*3]; void comp_subtree_sz(int u, int p = -1) { if(is_centr[u]) { subtree_sz[u] = 0; return; } subtree_sz[u] = 1; for(int v : tree[u]) { if(v == p) continue; comp_subtree_sz(v, u); subtree_sz[u] += subtree_sz[v]; } } int find_centroid(int u, int p, int mxsz) { for(int v : tree[u]) { if(v == p) continue; if(subtree_sz[v] > mxsz) return find_centroid(v, u, mxsz); } return u; } void decompose(int u, int p = -1, int layer=0) { if(is_centr[u]) return; comp_subtree_sz(u); int v = find_centroid(u, -1, subtree_sz[u]/2); ///cerr << "initializing centroid: " << v << '\n'; centroid_pars[v] = p; centroids[v] = Centroid(v, subtree_sz[u], layer); for(int w : tree[v]) { decompose(w, v, layer+1); } } void make_tree_binary(int u, int p = -1) { vec<int> ch{}; for(int v : tree_i[u]) { if(v==p) continue; ch.push_back(v); } if(ch.size() > 4) { int p2 = 1; while(p2 < ch.size()) { p2 *= 2; } int root = fi; tree_i[u].insert(root); tree_i[root].insert(u); for(int i = 2; i<p2; i++) { tree_i[i/2+fi-1].insert(i+fi-1); tree_i[i+fi-1].insert(i/2+fi-1); } for(int i = p2; i<p2+ch.size(); i++) { tree_i[i/2+fi-1].insert(ch[i-p2]); tree_i[ch[i-p2]].insert(i/2+fi-1); wn[i/2+fi-1] = 1; tree_i[ch[i-p2]].erase(u); tree_i[u].erase(ch[i-p2]); } fi += p2-1; } for(int v : tree[u]) { if(v == p) continue; make_tree_binary(v, u); } } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> N >> L; for(int i = 0; i<N-1; i++) { int u, v; cin >> u >> v; u--;v--; tree_i[u].insert(v); tree_i[v].insert(u); } for(int i = 0; i<N; i++) { cin >> H[i]; } auto start = chrono::high_resolution_clock::now(); make_tree_binary(0); if(false) { for(int i = 0; i<MXN*3; i++) { if(tree[i].size() > 0) { cerr << i << ":" << ' '; for(int v : tree[i]) cerr << v << ' '; cerr << '\n'; } } } for(int i = 0; i<MXN*3; i++) { tree[i] = vec<int>(tree_i[i].begin(), tree_i[i].end()); } auto stop = chrono::high_resolution_clock::now(); auto duration = chrono::duration_cast<chrono::milliseconds>(stop-start).count(); cerr << "Binary tree making took: " << duration << " milliseconds" << '\n'; start = chrono::high_resolution_clock::now(); decompose(0); stop = chrono::high_resolution_clock::now(); duration = chrono::duration_cast<chrono::milliseconds>(stop-start).count(); cerr << "Centroid decomposition: " << duration << " milliseconds" << '\n'; int Q; cin >> Q; while(Q--) { //cerr << "HERE0" << '\n'; int t; cin >> t; if(t == 2) { //cerr << "Here1" << '\n'; int u; cin >> u; if(cache.count(u)) { cout << cache[u] << '\n'; continue; } u--; int ans = 1; int ci = u; auto mult_ans = [&](int val) { ans *= val; ans %= L; }; while(ci != -1) { int d = centr_dists[u][centroids[ci].layer]; mult_ans(centroids[ci].contr.query_suffix(d)); for(int i = 0; i<centroids[ci].subtree_contrs.size(); i++) { if(centr_subtree_inds[u][centroids[ci].layer] != i) { mult_ans(centroids[ci].subtree_contrs[i].query_suffix(d)); } } ci = centroid_pars[ci]; //cerr << ci << '\n'; }; cout << ans << '\n'; } else { cache = {}; //cerr <<"HERE2" << '\n'; int u, d, w; cin >> u >> d >> w; u--; centroids[u].contr.upd(min(centroids[u].contr.n-1, d), {w}); int ci = centroid_pars[u]; while(ci != -1) { //cerr << "Cur Centroid: " << ci << '\n'; auto& c = centroids[ci]; int contr_d = d - centr_dists[u][c.layer]; if(contr_d < 0) { ci = centroid_pars[ci]; continue; } auto& st = c.subtree_contrs[centr_subtree_inds[u][c.layer]]; contr_d = min(contr_d, st.n-1); //cerr << st.n << '\n'; st.upd(contr_d, {w}); ci = centroid_pars[ci]; //cerr << ci << '\n'; } } } }

Compilation message (stderr)

sprinkler.cpp: In function 'void make_tree_binary(long long int, long long int)':
sprinkler.cpp:139:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  139 |   while(p2 < ch.size()) {
      |         ~~~^~~~~~~~~~~
sprinkler.cpp:149:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'long long unsigned int' [-Wsign-compare]
  149 |   for(int i = p2; i<p2+ch.size(); i++) {
      |                   ~^~~~~~~~~~~~~
sprinkler.cpp: In function 'int32_t main()':
sprinkler.cpp:233:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<FenwickTree>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  233 |     for(int i = 0; i<centroids[ci].subtree_contrs.size(); i++) {
      |                    ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...