【题解】[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); } }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530215.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(34)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示