TigerNick @ 2024-09-15 23:23:55
思路跟第二篇题解差不多,小数据没拍出错,大样例过不了,还有TLE是常数问题吗
#include <bits/stdc++.h>
#define int long long
#define MAXN 1000010
#define mod 998244353
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
int n,a[MAXN],m,op[MAXN],P[MAXN],V[MAXN],v,Q,f[MAXN];
int res[MAXN]; // 每个点的真实调用次数
int add[MAXN]; //最终每个点会加上的值
int cnt[MAXN]; //调用每个点会乘上的值
int indeg[MAXN],outdeg[MAXN]; //入度,出度
vector<int> p[MAXN]; //邻接表
vector<int> rt; //存放入度为 0 的点
int fp(int a,int b,int p)
{
if(!a) return 0;
int t=a%p,ans=1;
while(b)
{
if(b&1) ans=(ans*t)%p;
t=(t*t)%p;
b>>=1;
}
return ans;
}
void initin()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>op[i];
cnt[i]=1;
if(op[i]==1) cin>>P[i]>>V[i];
else if(op[i]==2) cin>>V[i],cnt[i]=V[i];
else
{
int c,v;cin>>c;
for(int j=1;j<=c;j++)
{
cin>>v;
p[i].push_back(v);
outdeg[i]++;
indeg[v]++;
}
}
}
cin>>Q;
for(int i=1;i<=Q;i++) cin>>f[i];
}
void dfs(int x)
{
for(int i=0;i<p[x].size();i++)
{
dfs(p[x][i]);
cnt[x]*=cnt[p[x][i]]; cnt[x]%=mod;
}
}
void topo_sort()
{
queue<pii> Q;
for(int i=0;i<rt.size();i++)
Q.push({rt[i],0});
while(!Q.empty())
{
int u=Q.front().fi,fa=Q.front().se;
Q.pop();
int mul=1;
for(int i=(int)p[u].size()-1;i>=0;i--)
{
int v=p[u][i];
res[v]+=mul*res[u]; res[v]%=mod;
mul*=cnt[v]; mul%=mod;
if(!(--indeg[v])) Q.push({v,u});
}
}
}
void solve()
{
initin();
for(int i=1;i<=m;i++) if(!indeg[i]) rt.push_back(i);
for(int i=0;i<rt.size();i++)
dfs(rt[i]);
int mul=1;
for(int i=Q;i>=1;i--)
{
res[f[i]]+=mul; res[f[i]]%=mod;
mul*=cnt[f[i]]; mul%=mod;
}
topo_sort();
int mmul=1;
for(int i=1;i<=m;i++)
{
if(!outdeg[i])
add[P[i]]+=res[i]*V[i],add[P[i]]%=mod;
}
for(int i=1;i<=Q;i++) mmul*=cnt[f[i]],mmul%=mod;
for(int i=1;i<=n;i++) cout<<(mmul*a[i]%mod+add[i])%mod<<" ";
}
signed main()
{
//freopen("call3.in","r",stdin);
//freopen("call3.myout","w",stdout);
ios::sync_with_stdio(0);//cin.tie(0);
int _T=1;//cin>>_T;
while(_T--)solve();
return 0;
}
by TigerNick @ 2024-09-16 01:06:44
已解决,dfs加上记忆化即可,不然会搜重