結果
| 問題 |
No.235 めぐるはめぐる (5)
|
| コンテスト | |
| ユーザー |
maine_honzuki
|
| 提出日時 | 2021-04-30 14:16:50 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,742 ms / 10,000 ms |
| コード長 | 3,609 bytes |
| コンパイル時間 | 4,796 ms |
| コンパイル使用メモリ | 267,644 KB |
| 最終ジャッジ日時 | 2025-01-21 02:22:18 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 3 |
ソースコード
//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;
}
}
}
maine_honzuki