[lnsyoj446/luoguP7077/CSP-S 2020] 函数调用
sol
将结果拆为 ,其中 为进行的乘法操作的总贡献, 为加法操作对第 个数的贡献。
如果没有函数 的话, 即为调用的所有函数 参数的积,并且容易发现,在调用了一次函数 之后,前面所有的函数 的贡献也会乘上其参数,因此可以计算出 表示函数 贡献的系数, 可以倒着进行计算。
考虑函数 ,由于没有递归操作,因此会形成一个 DAG,容易想到没有后效性的拓扑排序。
因此,先按照操作序列倒序枚举,计算 和 ,再根据拓扑序更新 和 即可,具体见代码
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 100005, M = N, mod = 998244353;
vector<int> ne[N];
int a[N], V[N], pos[N], mul[N], ad[N], typ[N], outd[N];
int f[N];
int n, m, q, d[N];
bool st[N];
void dfs(int u){
if (st[u]) return ;
st[u] = true;
if (typ[u] == 2) mul[u] = V[u];
else mul[u] = 1;
for (auto x : ne[u]) {
dfs(x);
mul[u] = (LL) mul[u] * mul[x] % mod;
}
}
int main(){
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
scanf("%d", &m);
for (int i = 1; i <= m; i ++ ) {
scanf("%d", &typ[i]);
if (typ[i] == 1) scanf("%d%d", &pos[i], &V[i]);
else if (typ[i] == 2) scanf("%d", &V[i]);
else {
int g;
scanf("%d", &g);
while (g -- ){
int t;
scanf("%d", &t);
ne[i].push_back(t);
outd[t] ++ ;
}
}
}
queue<int> que;
for (int i = 1; i <= m; i ++ )
if (!st[i] && !outd[i]) dfs(i), que.push(i);
scanf("%d", &q);
for (int i = 1; i <= q; i ++ ) scanf("%d", &d[i]);
int mult = 1;
for (int i = q; i; i -- ){
if (typ[d[i]] == 1) f[d[i]] = (f[d[i]] + mult) % mod;
else if (typ[d[i]] == 2) mult = (LL) mult * V[d[i]] % mod;
else f[d[i]] = (f[d[i]] + mult) % mod, mult = (LL) mult * mul[d[i]] % mod;
}
while (!que.empty()) {
int t = que.front();
que.pop();
if (typ[t] == 1) ad[pos[t]] = (ad[pos[t]] + (LL) f[t] * V[t] % mod) % mod;
if (typ[t] == 3) {
int temp = f[t];
for (int i = ne[t].size() - 1; i >= 0; i -- ){
int j = ne[t][i];
f[j] = (f[j] + temp) % mod;
temp = (LL) temp * mul[j] % mod;
outd[j] -- ;
if (!outd[j]) que.push(j);
}
}
}
for (int i = 1; i <= n; i ++ ) printf("%lld ", ((LL) a[i] * mult % mod + ad[i]) % mod);
}
蒟蒻犯的若至错误
- 和 混淆
分类:
题解 / 2025训练
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通