本来想趁着离职前的摸鱼时间刷题的。。。结果中途又是原神又是各种摸鱼x,结果一天居然只做了一题。
按着luogu比赛的顺序刷的,没想到是个T3,感觉也太水了…
T1大模拟不想写了。
这题就是显然对于每个位置
i
i
i,函数
j
j
j的作用就是
k
j
a
i
+
b
j
k_j a_i + b_j
kjai+bj。
那先拓扑排序一遍搞出每个函数的作用,然后再dp一遍得到每个函数的调用次数就好了。
最后的调用一堆函数也可以看成一个函数,于是就可以很方便的处理了。
//
// Created by bpm136 on 2020/11/10.
//
#include <bits/stdc++.h>
int const MAXN = 100000 + 5;
int const MOD = 998244353;
struct func {
int type;
int p, v;
std::vector<int> id;
} b[MAXN];
int a[MAXN];
int n, m;
bool vis[MAXN];
int du[MAXN];
int prod[MAXN];
int f[MAXN];
int ans[MAXN];
void color(int S) {
vis[S] = true;
auto q = std::queue<int>();
q.push(S);
while (!q.empty()) {
int now = q.front();
q.pop();
for (auto const &y : b[now].id)
if (!vis[y]) {
vis[y] = true;
q.push(y);
}
}
}
int get_prod(int id) {
if (prod[id] != -1)
return prod[id];
if (b[id].type == 1)
prod[id] = 1;
else if (b[id].type == 2)
prod[id] = b[id].v;
else {
prod[id] = 1;
for (auto const &y : b[id].id)
prod[id] = 1ll * prod[id] * get_prod(y) % MOD;
}
return prod[id];
}
void solve(int S) {
auto q = std::queue<int>();
q.push(S);
while (!q.empty()) {
int now = q.front();
q.pop();
if (b[now].type == 1) {
int p = b[now].p;
ans[p] = (ans[p] + 1ll * f[now] * b[now].v) % MOD;
} else if (b[now].type == 2) {
} else if (b[now].type == 3) {
int cnt = f[now];
for (int i = b[now].id.size() - 1; i >= 0; --i) {
int y = b[now].id[i];
f[y] = f[y] + cnt;
if (f[y] >= MOD)
f[y] -= MOD;
cnt = 1ll * cnt * prod[y] % MOD;
--du[y];
if (!du[y])
q.push(y);
}
}
}
}
int main() {
std::cin >> n;
for (int i = 0; i < n; ++i)
std::cin >> a[i];
std::cin >> m;
for (int i = 0; i < m; ++i) {
std::cin >> b[i].type;
if (b[i].type == 1) {
std::cin >> b[i].p >> b[i].v;
--b[i].p;
} else if (b[i].type == 2)
std::cin >> b[i].v;
else {
int num;
std::cin >> num;
b[i].id = std::vector<int>(num);
for (auto &v : b[i].id) {
std::cin >> v;
--v;
++du[v];
}
}
}
int num;
std::cin >> num;
b[m] = func{3, 0, 0, {}};
b[m].id.resize(num);
for (auto &v : b[m].id) {
std::cin >> v;
--v;
++du[v];
}
color(m);
for (int i = 0; i <= m; ++i)
if (!vis[i])
for (auto const &y : b[i].id)
--du[y];
std::fill(prod, prod + m + 1, -1);
int mul_coef = get_prod(m);
// std::cout << "mul_coef = " << mul_coef << '\n';
// for (int i = 0; i < n; ++i)
// std::cout << prod[i] << ' ';
// std::cout << '\n';
f[m] = 1;
solve(m);
// for (int i = 0; i < n; ++i)
// std::cout << f[i] << ' ';
// std::cout << '\n';
// for (int i = 0; i < n; ++i)
// std::cout << ans[i] << ' ';
// std::cout << '\n';
for (int i = 0; i < n; ++i)
std::cout << (1ll * a[i] * mul_coef + ans[i]) % MOD << ' ';
return 0;
}