結果
問題 | No.235 めぐるはめぐる (5) |
ユーザー | maine_honzuki |
提出日時 | 2021-04-30 14:16:50 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,759 ms / 10,000 ms |
コード長 | 3,609 bytes |
コンパイル時間 | 4,978 ms |
コンパイル使用メモリ | 278,552 KB |
実行使用メモリ | 37,888 KB |
最終ジャッジ日時 | 2024-07-18 11:52:46 |
合計ジャッジ時間 | 13,164 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,759 ms
36,736 KB |
testcase_01 | AC | 1,280 ms
37,888 KB |
testcase_02 | AC | 1,644 ms
36,864 KB |
ソースコード
//https://ncode.syosetu.com/n4830bu/235/ #include "atcoder/all" using namespace atcoder; #include <bits/stdc++.h> using namespace std; struct HeavyLightDecomposition { vector<vector<int>> G; vector<int> sz, idx, head, par; HeavyLightDecomposition(vector<vector<int>>& G) : G(G), sz(G.size()), idx(G.size()), head(G.size()), par(G.size()) { build(); } int dfs_sz(int now, int p) { par[now] = p; sz[now] = 1; if (G[now].size() && G[now][0] == p) swap(G[now][0], G[now].back()); for (auto&& nxt : G[now]) { if (nxt == p) continue; sz[now] += dfs_sz(nxt, now); if (sz[G[now][0]] < sz[nxt]) swap(G[now][0], nxt); } return sz[now]; } void dfs_hld(int now, int p, int& t) { idx[now] = t++; for (auto&& nxt : G[now]) { if (nxt == p) continue; head[nxt] = (G[now][0] == nxt ? head[now] : nxt); dfs_hld(nxt, now, t); } } void build() { dfs_sz(0, -1); dfs_hld(0, -1, *make_unique<int>(0)); } template <typename T, typename F, typename G> T prod(int u, int v, const T& e, const F& f, const G& g) { T l = e, r = e; while (true) { if (idx[u] > idx[v]) { swap(u, v); swap(l, r); } if (head[u] == head[v]) break; l = f(g(idx[head[v]], idx[v] + 1), l); v = par[head[v]]; } return f(f(g(idx[u], idx[v] + 1), l), r); } template <typename Q> void apply(int u, int v, const Q& q) { while (true) { if (idx[u] > idx[v]) swap(u, v); if (head[u] == head[v]) break; q(idx[head[v]], idx[v] + 1); v = par[head[v]]; } q(idx[u], idx[v] + 1); } }; using Mint = modint1000000007; struct book { Mint cost, infl; }; book op(book a, book b) { return {a.cost + b.cost, a.infl + b.infl}; } book e() { return {Mint{0}, Mint{0}}; } book mapping(Mint f, book a) { return {a.cost + f * a.infl, a.infl}; } Mint composition(Mint f, Mint g) { return f + g; } Mint id() { return Mint{0}; } int main() { int N; vector<int> S, C; vector<vector<int>> G; cin >> N; S.resize(N); for (auto&& x : S) { cin >> x; } C.resize(N); for (auto&& x : C) { cin >> x; } G.resize(N); for (int i = 0; i < N - 1; i++) { int a, b; cin >> a >> b; a--; b--; G[a].emplace_back(b); G[b].emplace_back(a); } HeavyLightDecomposition hld(G); vector<book> initial(N); for (int i = 0; i < N; i++) { initial[hld.idx[i]] = {S[i], C[i]}; } lazy_segtree<book, op, e, Mint, mapping, composition, id> seg(initial); int Q; cin >> Q; while (Q--) { int query; cin >> query; if (query == 0) { int X, Y, Z; cin >> X >> Y >> Z; X--; Y--; hld.apply(X, Y, [&](int u, int v) { seg.apply(u, v, Mint{Z}); }); } else { int X, Y; cin >> X >> Y; X--; Y--; cout << (hld.prod(X, Y, Mint{0}, [](Mint a, Mint b) { return a + b; }, [&](int u, int v) { return seg.prod(u, v).cost; })) .val() << endl; } } }