【题解】[CSP-S2020] 函数调用
难。。。
第二次做这道题,还是思考了 1.5h 才胡出思路。
但是部分分很好拿。
考虑一种思想:将子节点的部分信息存储到父节点上,通过对操作序列的预判,向父节点传递标记,再对 DAG 上的每一个节点统计答案。
考虑对每个 复合函数 打一个标记,表示 对于当前操作涉及的所有操作 都会乘上一个 val 。
现在我们站在离线的角度思考这个问题,维护 add 和 val 标记,对于第 i 个数输出 a[i]*val+add 即可。
时间复杂度 O(n+∑c_i) 。总用时 2.5h 。(乐观估计)
#include <bits/stdc++.h>
#define db double
#define ll long long
#define eps 1e-15
using namespace std;
const int N=1e5+5;
const int mod=998244353;
int n,m,c,func[N],deg[N],tp[N],vis[N];
ll Mul=1,a[N],b[N],mul[N],add[N],p[N],v[N];
vector<int> g[N];
queue<int> Q;
//x 执行 val 次
//简单地想,直接往儿子传递 val (乘法标记)
//add [i] 表示当前函数对它所涉及的函数的影响 (调用次数)
//没有考虑 0 的情况 哈哈哈 (注意读数据范围)
inline int read() {
int x=0,f=1; char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}
return x*f;
}
void dfs(int i) {
if(vis[i]) return;
vis[i]=1;
mul[i]=1;
for(auto j:g[i]) {
dfs(j);
mul[i]=mul[i]*mul[j]%mod;
}
}
void solve1() {
for(int i=1;i<=m;i++) {
dfs(i);
}
}
void Add(ll &x,ll y) {
x=(x+y)%mod;
}
//关键代码
void solve2() {
for(int i=c;i>=1;i--) {
Add(add[func[i]],Mul);
Mul=Mul*mul[func[i]]%mod;
}
for(int i=1;i<=m;i++) {
if(deg[i]==0) {
Q.push(i);
}
// printf("mul[%d]=%lld\n",i,mul[i]);
}
while(Q.size()) {
int x=Q.front(); Q.pop();
// printf("add[%d]=%lld\n",x,add[x]);
if(tp[x]==3) {
reverse(g[x].begin(),g[x].end());
for(auto y:g[x]) {
if(--deg[y]==0) Q.push(y);
Add(add[y],add[x]);
add[x]=add[x]*mul[y]%mod;
}
}
}
}
void solve3() {
for(int i=1;i<=m;i++) {
if(tp[i]==1) {
b[p[i]]=(b[p[i]]+v[i]*add[i])%mod;
}
}
}
int main() {
// freopen("call3.in","r",stdin);
// freopen("call3.out","w",stdout);
n=read();
for(int i=1;i<=n;i++) a[i]=read();
m=read();
for(int i=1;i<=m;i++) {
tp[i]=read();
if(tp[i]==1) {
p[i]=read(),v[i]=read();
mul[i]=vis[i]=1;
}
else if(tp[i]==2) {
v[i]=mul[i]=read();
vis[i]=1;
}
else if(tp[i]==3) {
int k=read();
for(int j=1;j<=k;j++) {
int x=read();
deg[x]++;
g[i].push_back(x);
}
}
}
c=read();
for(int i=1;i<=c;i++) func[i]=read();
solve1();
solve2();
solve3();
for(int i=1;i<=n;i++) {
printf("%lld ",(a[i]*Mul+b[i])%mod);
}
}

浙公网安备 33010602011771号