题目
思路
考场上思考时候怎么也无法合并,下来发现如果是
a
∗
b
+
a
∗
c
∗
d
a*b+a*c*d
a∗b+a∗c∗d 可以合并为
a
∗
(
b
+
d
∗
d
)
a*(b+d*d)
a∗(b+d∗d) ,也就是可以维护系数或者说执行次数
首先来看看这个例子:
首先要倒着来
那么就应该是:
+
5
∗
2
+5*2
+5∗2
假设
3
3
3 函数执行次数是
3
3
3
然后经历了
2
2
2 函数变成
∗
2
*2
∗2
那么相当于
1
1
1 执行
6
6
6 次数
发现一个
1
1
1 的贡献为
a
∗
s
u
f
m
u
l
a*sufmul
a∗sufmul
具体而言每个函数维护两个值:
m
u
l
i
:
执
行
完
函
数
i
后
系
数
a
变
为
a
∗
m
u
l
i
mul_i:执行完函数 i 后系数a变为a*mul_i
muli:执行完函数i后系数a变为a∗muli
f
i
:
i
函
数
执
行
次
数
f_i:i 函数执行次数
fi:i函数执行次数
然后可以先
d
f
s
dfs
dfs 记忆化处理
m
u
l
mul
mul 然后拓扑排序处理
f
f
f
计算
f
f
f 时候对于儿子的
m
u
l
mul
mul 要后缀乘法,实现时候重复利用了
f
f
f
代码
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<cctype>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define ULL unsigned long long
int read(){
bool f=0;int x=0;char c=getchar();
while(!isdigit(c)) f=(c=='-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
return !f?x:-x;
}
void print(int x){
if(x<10){
if(x<0) putchar('-'),x=-x;
else{
putchar('0'+x);
return ;
}
}
print(x/10);
putchar('0'+x%10);
return ;
}
#define fi first
#define se second
#define mp make_pair
const int MAXN=100000;
const int INF=0x3f3f3f3f;
const int Mod=998244353;
int Sub(int x,int y){x-=y;return x<0?x+Mod:x;}
int Mul(LL x,int y){x*=y;return x>=Mod?x%Mod:x;}
int Add(int x,int y){x+=y;return x>=Mod?x-Mod:x;}
int a[MAXN+5];
bool vis[MAXN+5];
int de[MAXN+5],id[MAXN+5];
int f[MAXN+5],mul[MAXN+5];
int ty[MAXN+5],p[MAXN+5],V[MAXN+5];
vector<int> G[MAXN+5];
void GetMul(int u){
vis[u]=1;
for(int i=0;i<(int)G[u].size();i++){
int v=G[u][i];
if(vis[v]){
mul[u]=Mul(mul[u],mul[v]);
continue;
}
GetMul(v);
mul[u]=Mul(mul[u],mul[v]);
}
return ;
}
queue<int> Que;
int main(){
freopen("call.in","r",stdin);
freopen("call.out","w",stdout);
int n=read();
for(int i=1;i<=n;i++)
a[i]=read();
int m=read();
for(int i=1;i<=m;i++){
ty[i]=read();
if(ty[i]==1)
mul[i]=1,p[i]=read(),V[i]=read();
else if(ty[i]==2)
mul[i]=read();
else{
mul[i]=1;
int c=read();
for(int j=1,x;j<=c;j++)
G[i].push_back(x=read()),de[x]++;
}
}
for(int i=1;i<=m;i++)
if(!de[i])
G[0].push_back(i),de[i]++;
mul[0]=1,GetMul(0);
int Q=read(),k=1;
for(int i=1;i<=Q;i++)
id[i]=read();
for(int q=Q;q>=1;q--){
f[id[q]]=Add(f[id[q]],k);
k=Mul(k,mul[id[q]]);
}
for(int i=1;i<=n;i++)
a[i]=Mul(a[i],k);
Que.push(0);
while(!Que.empty()){
int u=Que.front();
Que.pop();
for(int i=G[u].size()-1;i>=0;i--){
int v=G[u][i];
f[v]=Add(f[v],f[u]);
f[u]=Mul(f[u],mul[v]);
if(!--de[v])
Que.push(v);
}
}
for(int i=1;i<=m;i++)
if(ty[i]==1)
a[p[i]]=Add(a[p[i]],Mul(V[i],f[i]));
for(int i=1;i<=n;i++)
print(a[i]),putchar(i==n?'\n':' ');
return 0;
}