陈年旧账。
题目 讲解我们需要将这三种函数之间的互相影响的关系找出来。
可以发现操作一是最基础的,所以我们可以以此来计算贡献。
考虑操作二对操作一的影响,发现影响范围前面所有的操作一,显然我们需要逆序做。假如是乘 \(mul\),那么相当于操作一执行 \(mul\) 次,这个思想比较关键。
考虑操作三调用了很多复杂函数,但由于我们只考虑对操作一的影响,所以还是从后往前记录操作二的乘积,往前有操作一的时候乘上这个记录的值即可,相当于逆序求出操作一执行次数。
具体实现可以将 \(0\) 号点向操作序列连边,提前处理一下每个函数会将整体乘上多少,然后在 DAG 上拓扑排序即可。
代码 说实话,挺短//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std;
typedef long long LL;
const int MAXN = 100005;
const int MOD = 998244353;
int n,m;
int a[MAXN],mul[MAXN],add[MAXN],pos[MAXN],cnt[MAXN],deg[MAXN];
LL Read()
{
LL x = 0,f = 1; char c = getchar();
while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
return x * f;
}
TT void Put1(T x)
{
if(x > 9) Put1(x/10);
putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
if(x < 0) putchar('-'),x = -x;
Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}
vector<int> G[MAXN];
bool vis[MAXN];
void dfs(int x)
{
vis[x] = 1;
for(auto v : G[x])
{
if(!vis[v]) dfs(v);
mul[x] = 1ll * mul[x] * mul[v] % MOD;
}
}
void topu()
{
queue<int> q;
for(int i = 0;i <= m;++ i) if(!deg[i]) q.push(i);
while(!q.empty())
{
int x = q.front(),now = 1; q.pop();
reverse(G[x].begin(),G[x].end());
for(auto v : G[x])
{
cnt[v] = (cnt[v] + 1ll * cnt[x] * now) % MOD;
now = 1ll * now * mul[v] % MOD;
if(!(--deg[v])) q.push(v);
}
}
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n = Read();
for(int i = 1;i <= n;++ i) a[i] = Read();
m = Read();
for(int i = 1;i <= m;++ i)
{
int opt = Read(); mul[i] = 1;
if(opt == 1) pos[i] = Read(),add[i] = Read();
else if(opt == 2) mul[i] = Read();
else
{
int k = Read();
for(int j = 0,v;j < k;++ j)
{
v = Read();
G[i].emplace_back(v);
++deg[v];
}
}
}
mul[0] = cnt[0] = 1;
for(int Q = Read(); Q ;-- Q)
{
int v = Read();
G[0].emplace_back(v);
++deg[v];
}
for(int i = 0;i <= m;++ i) if(!vis[i]) dfs(i);
topu();
for(int i = 1;i <= n;++ i) a[i] = 1ll * a[i] * mul[0] % MOD;
for(int i = 1;i <= m;++ i)
if(pos[i]) a[pos[i]] = (a[pos[i]] + 1ll * cnt[i] * add[i]) % MOD;
for(int i = 1;i <= n;++ i) Put(a[i],' ');
return 0;
}