This documentation is automatically generated by competitive-verifier/competitive-verifier
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_E"
#include <bits/stdc++.h>
using namespace std;
#include "../../../../data-structure/segment-tree/LazySegmentTree.hpp"
#include "../../../../graph/tree/HeavyLightDecomposition.hpp"
using F = long long;
struct S {
long long val;
int siz;
};
S op(S a, S b) {
return {a.val + b.val, a.siz + b.siz};
}
S e() {
return {0, 0};
}
S mapping(F f, S x) { return {x.val + f * x.siz, x.siz}; }
F composition(F f, F g) { return f + g; }
F id() { return 0; }
int main() {
cin.tie(0)->sync_with_stdio(0);
int n, q;
cin >> n;
vector<vector<pair<int, S>>> g(n);
vector<S> nodew(n, e());
for (int i = 0; i < n; i++) {
int k;
cin >> k;
for (int j = 0; j < k; j++) {
int c;
cin >> c;
g[c].push_back({i, {0, 1}});
g[i].push_back({c, {0, 1}});
}
}
hld<S, op, e, F, mapping, composition, id, S, op, e, F, mapping, composition, id> h(g, nodew);
cin >> q;
for (int i = 0; i < q; i++) {
int com;
cin >> com;
if (com == 0) {
int v, w;
cin >> v >> w;
h.apply_edge(0, v, w);
} else {
int u;
cin >> u;
cout << h.prod_edge(0, u).val << "\n";
}
}
}
#line 1 "verify/AizuOnlineJudge/graph/tree/GRL_5_E.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_E"
#include <bits/stdc++.h>
using namespace std;
#line 1 "data-structure/segment-tree/LazySegmentTree.hpp"
template <class S,
auto op,
auto e,
class F,
auto mapping,
auto composition,
auto id>
struct lazy_segtree {
private:
unsigned int seg_bit_ceil(unsigned int n) {
unsigned int x = 1;
while (x < (unsigned int)(n)) x *= 2;
return x;
}
public:
static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
"op must work as S(S, S)");
static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
"e must work as S()");
static_assert(
std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
"mapping must work as F(F, S)");
static_assert(
std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
"compostiion must work as F(F, F)");
static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
"id must work as F()");
lazy_segtree() : lazy_segtree(0) {}
explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
size = (int)seg_bit_ceil((unsigned int)(_n));
log = __builtin_ctz((unsigned int)size);
d = std::vector<S>(2 * size, e());
lz = std::vector<F>(size, id());
for (int i = 0; i < _n; i++) d[size + i] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, S x) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
return d[p];
}
S prod(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return e();
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
S sml = e(), smr = e();
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() { return d[1]; }
void apply(int p, F f) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = mapping(f, d[p]);
for (int i = 1; i <= log; i++) update(p >> i);
}
void apply(int l, int r, F f) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return;
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
{
int l2 = l, r2 = r;
while (l < r) {
if (l & 1) all_apply(l++, f);
if (r & 1) all_apply(--r, f);
l >>= 1;
r >>= 1;
}
l = l2;
r = r2;
}
for (int i = 1; i <= log; i++) {
if (((l >> i) << i) != l) update(l >> i);
if (((r >> i) << i) != r) update((r - 1) >> i);
}
}
template <bool (*g)(S)>
int max_right(int l) {
return max_right(l, [](S x) { return g(x); });
}
template <class G>
int max_right(int l, G g) {
assert(0 <= l && l <= _n);
assert(g(e()));
if (l == _n) return _n;
l += size;
for (int i = log; i >= 1; i--) push(l >> i);
S sm = e();
do {
while (l % 2 == 0) l >>= 1;
if (!g(op(sm, d[l]))) {
while (l < size) {
push(l);
l = (2 * l);
if (g(op(sm, d[l]))) {
sm = op(sm, d[l]);
l++;
}
}
return l - size;
}
sm = op(sm, d[l]);
l++;
} while ((l & -l) != l);
return _n;
}
template <bool (*g)(S)>
int min_left(int r) {
return min_left(r, [](S x) { return g(x); });
}
template <class G>
int min_left(int r, G g) {
assert(0 <= r && r <= _n);
assert(g(e()));
if (r == 0) return 0;
r += size;
for (int i = log; i >= 1; i--) push((r - 1) >> i);
S sm = e();
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!g(op(d[r], sm))) {
while (r < size) {
push(r);
r = (2 * r + 1);
if (g(op(d[r], sm))) {
sm = op(d[r], sm);
r--;
}
}
return r + 1 - size;
}
sm = op(d[r], sm);
} while ((r & -r) != r);
return 0;
}
private:
int _n, size, log;
std::vector<S> d;
std::vector<F> lz;
void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
void all_apply(int k, F f) {
d[k] = mapping(f, d[k]);
if (k < size) lz[k] = composition(f, lz[k]);
}
void push(int k) {
all_apply(2 * k, lz[k]);
all_apply(2 * k + 1, lz[k]);
lz[k] = id();
}
};
#line 2 "graph/tree/HeavyLightDecomposition.hpp"
template <class S, auto ops, auto es, class F, auto mappings, auto compositionf, auto idf, class T, auto opt, auto et, class G, auto mappingt, auto compositiong, auto idg>
class hld {
private:
int n;
vector<int> subtree, depth, hl, ind, parent, top;
vector<bool> seen;
vector<T> dist_top_p;
lazy_segtree<S, ops, es, F, mappings, compositionf, idf> nodeseg, noderseg;
lazy_segtree<T, opt, et, G, mappingt, compositiong, idg> pathseg, pathrseg;
int indr(int x) {
return abs(ind[x] - (n - 1)) - 1;
}
int indrn(int x) {
return abs(ind[x] - (n - 1));
}
int rec_sub(vector<vector<pair<int, T>>> &g, int cur, int d) {
int sub = 0;
for (auto nex : g[cur]) {
if (seen[nex.first]) continue;
seen[nex.first] = 1;
parent[nex.first] = cur;
sub += rec_sub(g, nex.first, d + 1);
}
subtree[cur] = sub + 1;
depth[cur] = d;
return subtree[cur];
}
void rec_hld(vector<vector<pair<int, T>>> &g, int cur) {
ind[cur] = int(hl.size());
seen[cur] = 1;
hl.push_back(cur);
int sub = 0;
int ind = -1;
for (auto nex : g[cur]) {
if (subtree[nex.first] > sub and !seen[nex.first]) {
sub = subtree[nex.first];
ind = nex.first;
}
}
if (ind != -1) {
top[ind] = top[cur];
rec_hld(g, ind);
for (auto nex : g[cur]) {
if (nex.first != ind and !seen[nex.first]) {
top[nex.first] = nex.first;
dist_top_p[nex.first] = nex.second;
rec_hld(g, nex.first);
}
}
}
}
public:
hld(vector<vector<pair<int, T>>> &g, vector<S> nodew, int root = 0) {
n = g.size();
seen.resize(n, 0);
subtree.resize(n, 0);
ind.resize(n, 0);
depth.resize(n, 0);
top.resize(n, 0);
dist_top_p.resize(n, et());
parent.resize(n, -1);
seen[root] = 1;
rec_sub(g, root, 0);
for (int i = 0; i < n; i++) seen[i] = 0;
seen[root] = 1;
top[root] = root;
rec_hld(g, root);
vector<S> v(n, es());
vector<T> z(n, et());
for (int i = 0; i < n; i++) v[i] = nodew[hl[i]];
nodeseg = lazy_segtree<S, ops, es, F, mappings, compositionf, idf>(v);
reverse(v.begin(), v.end());
noderseg = lazy_segtree<S, ops, es, F, mappings, compositionf, idf>(v);
for (int i = 1; i < n; i++) {
int prev = hl[i - 1];
int cur = hl[i];
if (top[prev] != top[cur]) continue;
for (auto p : g[prev]) {
if (p.first == cur) {
z[i] = p.second;
}
}
}
pathseg = lazy_segtree<T, opt, et, G, mappingt, compositiong, idg>(z);
reverse(z.begin(), z.end());
pathrseg = lazy_segtree<T, opt, et, G, mappingt, compositiong, idg>(z);
}
// path i -> j
S prod_node(int i, int j) {
S prodsl = es();
S prodsr = es();
while (1) {
if (top[i] == top[j]) {
if (depth[i] > depth[j]) {
prodsl = ops(prodsl, noderseg.prod(indrn(i), indrn(j) + 1));
} else {
prodsr = ops(nodeseg.prod(ind[i], ind[j] + 1), prodsr);
}
break;
}
if (depth[top[i]] > depth[top[j]]) {
prodsl = ops(prodsl, noderseg.prod(indrn(i), indrn(top[i]) + 1));
i = parent[top[i]];
} else {
prodsr = ops(nodeseg.prod(ind[top[j]], ind[j] + 1), prodsr);
j = parent[top[j]];
}
}
return ops(prodsl, prodsr);
}
// path i -> j
T prod_edge(int i, int j) {
T prodl = et();
T prodr = et();
while (1) {
if (top[i] == top[j]) {
if (depth[i] > depth[j]) {
prodl = opt(prodl, pathrseg.prod(indr(i) + 1, indr(j) + 1));
} else {
prodr = opt(pathseg.prod(ind[i] + 1, ind[j] + 1), prodr);
}
break;
}
if (depth[top[i]] > depth[top[j]]) {
prodl = opt(prodl, pathrseg.prod(indr(i) + 1, indr(top[i]) + 1));
prodl = opt(prodl, dist_top_p[top[i]]);
i = parent[top[i]];
} else {
prodr = opt(pathseg.prod(ind[top[j]] + 1, ind[j] + 1), prodr);
prodr = opt(dist_top_p[top[j]], prodr);
j = parent[top[j]];
}
}
return opt(prodl, prodr);
}
void set_edge(int u, int v, T w) {
if (top[u] == top[v]) {
if (depth[u] > depth[v]) {
pathrseg.set(indr(v), w);
pathseg.set(ind[u], w);
} else {
pathseg.set(ind[v], w);
pathrseg.set(indr(u), w);
}
} else {
if (parent[v] == u) {
dist_top_p[v] = w;
} else {
dist_top_p[u] = w;
}
}
}
void set_node(int u, S x) {
nodeseg.set(ind[u], nodeseg.get(ind[u]) + x);
noderseg.set(indrn(u), noderseg.get(indrn(u)) + x);
}
// path i -> j
void apply_edge(int i, int j, G x) {
while (1) {
if (top[i] == top[j]) {
if (depth[i] > depth[j]) {
pathrseg.apply(indr(i) + 1, indr(j) + 1, x);
} else {
pathseg.apply(ind[i] + 1, ind[j] + 1, x);
}
break;
}
if (depth[top[i]] > depth[top[j]]) {
pathrseg.apply(indr(i) + 1, indr(top[i]) + 1, x);
dist_top_p[top[i]] = mappingt(x, dist_top_p[top[i]]);
i = parent[top[i]];
} else {
pathseg.apply(ind[top[j]] + 1, ind[j] + 1, x);
dist_top_p[top[j]] = mappingt(x, dist_top_p[top[j]]);
j = parent[top[j]];
}
}
}
// path i -> j
void apply_node(int i, int j, F x) {
while (1) {
if (top[i] == top[j]) {
if (depth[i] > depth[j]) {
noderseg.apply(indrn(i), indrn(j) + 1, x);
} else {
nodeseg.apply(ind[i], ind[j] + 1, x);
}
break;
}
if (depth[top[i]] > depth[top[j]]) {
noderseg.apply(indrn(i), indrn(top[i]) + 1, x);
i = parent[top[i]];
} else {
nodeseg.apply(ind[top[j]], ind[j] + 1, x);
j = parent[top[j]];
}
}
}
};
#line 8 "verify/AizuOnlineJudge/graph/tree/GRL_5_E.test.cpp"
using F = long long;
struct S {
long long val;
int siz;
};
S op(S a, S b) {
return {a.val + b.val, a.siz + b.siz};
}
S e() {
return {0, 0};
}
S mapping(F f, S x) { return {x.val + f * x.siz, x.siz}; }
F composition(F f, F g) { return f + g; }
F id() { return 0; }
int main() {
cin.tie(0)->sync_with_stdio(0);
int n, q;
cin >> n;
vector<vector<pair<int, S>>> g(n);
vector<S> nodew(n, e());
for (int i = 0; i < n; i++) {
int k;
cin >> k;
for (int j = 0; j < k; j++) {
int c;
cin >> c;
g[c].push_back({i, {0, 1}});
g[i].push_back({c, {0, 1}});
}
}
hld<S, op, e, F, mapping, composition, id, S, op, e, F, mapping, composition, id> h(g, nodew);
cin >> q;
for (int i = 0; i < q; i++) {
int com;
cin >> com;
if (com == 0) {
int v, w;
cin >> v >> w;
h.apply_edge(0, v, w);
} else {
int u;
cin >> u;
cout << h.prod_edge(0, u).val << "\n";
}
}
}