結果
問題 | No.235 めぐるはめぐる (5) |
ユーザー | pekempey |
提出日時 | 2015-11-27 18:14:59 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 1,546 ms / 10,000 ms |
コード長 | 3,940 bytes |
コンパイル時間 | 1,852 ms |
コンパイル使用メモリ | 175,216 KB |
実行使用メモリ | 30,948 KB |
最終ジャッジ日時 | 2024-09-13 23:05:30 |
合計ジャッジ時間 | 8,229 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,546 ms
30,164 KB |
testcase_01 | AC | 863 ms
30,948 KB |
testcase_02 | AC | 1,490 ms
30,336 KB |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:119:25: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 119 | rep (i, N) scanf("%d", &S[i]); | ~~~~~^~~~~~~~~~~~~ main.cpp:120:25: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 120 | rep (i, N) scanf("%d", &C[i]); | ~~~~~^~~~~~~~~~~~~ main.cpp:137:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 137 | scanf("%d", &q); | ~~~~~^~~~~~~~~~ main.cpp:140:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 140 | scanf("%d%d%d", &x, &y, &z); | ~~~~~^~~~~~~~~~~~~~~~~~~~~~ main.cpp:150:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 150 | scanf("%d%d", &x, &y); | ~~~~~^~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h> #define GET_MACRO(a, b, c, NAME, ...) NAME #define rep(...) GET_MACRO(__VA_ARGS__, rep3, rep2)(__VA_ARGS__) #define rep2(i, a) rep3 (i, 0, a) #define rep3(i, a, b) for (int i = (a); i < (b); i++) #define repr(...) GET_MACRO(__VA_ARGS__, repr3, repr2)(__VA_ARGS__) #define repr2(i, a) repr3 (i, 0, a) #define repr3(i, a, b) for (int i = (b) - 1; i >= (a); i--) #define chmin(a, b) ((b) < a && (a = (b), true)) #define chmax(a, b) (a < (b) && (a = (b), true)) using namespace std; typedef long long ll; const ll mod = 1e9 + 7; ll modulo(ll a) { a %= mod; a += mod; a %= mod; return a; } struct HL { vector<vector<int>> g; vector<int> vid, depth, head, parent, size; int u, v, k; HL(int n) : g(n), vid(n), depth(n), head(n), parent(n), size(n, 1), k(0) {} void add(int u, int v) { g[u].push_back(v); g[v].push_back(u); } void build() { dfs(0); dfs2(0); } void dfs(int curr, int prev = -1) { head[curr] = curr; parent[curr] = prev; rep (i, g[curr].size()) if (g[curr][i] != prev) { int next = g[curr][i]; depth[next] = depth[curr] + 1; dfs(next, curr); size[curr] += size[next]; if (size[g[curr][0]] <= size[next]) swap(g[curr][0], g[curr][i]); } } void dfs2(int curr, int prev = -1) { vid[curr] = k++; rep (i, g[curr].size()) if (g[curr][i] != prev) { if (!i) head[g[curr][i]] = head[curr]; dfs2(g[curr][i], curr); } } void set(int u, int v) { this->u = u, this->v = v; } pair<int, int> next() { if (depth[head[u]] < depth[head[v]]) swap(u, v); pair<int, int> res = minmax(vid[u], head[u] == head[v] ? vid[v] : vid[head[u]]); u = head[u] == head[v] ? -1 : parent[head[u]]; res.second++; return res; } bool has_next() { return u != -1; } }; struct SegmentTree { vector<ll> seg, lazy, wsum; int size; SegmentTree(int n) { size = 1; while (size < n) size *= 2; seg.resize(size * 2); lazy.resize(size * 2); wsum.resize(size + 1); } void set(int k, ll v, ll w) { seg[k + size - 1] = v; wsum[k + 1] = w; } void build() { rep (i, 1, wsum.size()) (wsum[i] += wsum[i - 1]) %= mod; repr (i, size - 1) { (seg[i] = seg[i * 2 + 1] + seg[i * 2 + 2]) %= mod; } } void push(int k, int l, int r) { if (lazy[k] != 0) { seg[k] += lazy[k] * (wsum[r] - wsum[l]); seg[k] = modulo(seg[k]); if (r - l > 1) { (lazy[k * 2 + 1] += lazy[k]) %= mod; (lazy[k * 2 + 2] += lazy[k]) %= mod; } lazy[k] = 0; } } void update(int a, int b, ll v, int k, int l, int r) { push(k, l, r); if (r <= a || b <= l) return; if (a <= l && r <= b) { lazy[k] = v; push(k, l, r); } else { update(a, b, v, k * 2 + 1, l, (l + r) / 2); update(a, b, v, k * 2 + 2, (l + r) / 2, r); seg[k] = (seg[k * 2 + 1] + seg[k * 2 + 2]) % mod; } } void update(int a, int b, ll v) { update(a, b, v, 0, 0, size); } ll query(int a, int b, int k, int l, int r) { push(k, l, r); if (r <= a || b <= l) return 0; if (a <= l && r <= b) return seg[k]; ll x = query(a, b, k * 2 + 1, l, (l + r) / 2); ll y = query(a, b, k * 2 + 2, (l + r) / 2, r); return (x + y) % mod; } ll query(int a, int b) { return query(a, b, 0, 0, size); } }; int main() { int N; cin >> N; vector<int> S(N), C(N); rep (i, N) scanf("%d", &S[i]); rep (i, N) scanf("%d", &C[i]); HL hl(N); rep (i, N - 1) { int a, b; cin >> a >> b; hl.add(a - 1, b - 1); } hl.build(); SegmentTree tr(N); rep (i, N) { tr.set(hl.vid[i], S[i], C[i]); } tr.build(); int Q; cin >> Q; while (Q--) { int q; scanf("%d", &q); if (q == 0) { int x, y, z; scanf("%d%d%d", &x, &y, &z); x--; y--; hl.set(x, y); while (hl.has_next()) { auto p = hl.next(); tr.update(p.first, p.second, z); } } else { int x, y; scanf("%d%d", &x, &y); x--; y--; hl.set(x, y); ll ans = 0; while (hl.has_next()) { auto p = hl.next(); (ans += tr.query(p.first, p.second)) %= mod; } printf("%d\n", (int)ans); } } }