当前位置: 首页 > news >正文

题解:洛谷 P7077 [CSP-S 2020] 函数调用

本文分享的必刷题目是从蓝桥云课洛谷AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现!

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

洛谷:P7077 [CSP-S 2020] 函数调用 - 洛谷

【题目描述】

函数是各种编程语言中一项重要的概念,借助函数,我们总可以将复杂的任务分解成一个个相对简单的子任务,直到细化为十分简单的基础操作,从而使代码的组织更加严密、更加有条理。然而,过多的函数调用也会导致额外的开销,影响程序的运行效率。

某数据库应用程序提供了若干函数用以维护数据。已知这些函数的功能可分为三类:

  1. 将数据中的指定元素加上一个值;
  2. 将数据中的每一个元素乘以一个相同值;
  3. 依次执行若干次函数调用,保证不会出现递归(即不会直接或间接地调用本身)。

在使用该数据库应用时,用户可一次性输入要调用的函数序列(一个函数可能被调用多次),在依次执行完序列中的函数后,系统中的数据被加以更新。某一天,小 A 在应用该数据库程序处理数据时遇到了困难:由于频繁而低效的函数调用,系统在执行操作时进入了无响应的状态,他只好强制结束了数据库程序。为了计算出正确数据,小 A 查阅了软件的文档,了解到每个函数的具体功能信息,现在他想请你根据这些信息帮他计算出更新后的数据应该是多少。

【输入】

第一行一个正整数n nn,表示数据的个数。
第二行n nn个整数,第i ii个整数表示下标为i ii的数据的初始值为a i a_iai
第三行一个正整数m mm,表示数据库应用程序提供的函数个数。函数从1 ∼ m 1 \sim m1m编号。
接下来m mm行中,第j jj1 ≤ j ≤ m 1 \le j \le m1jm)行的第一个整数为T j T_jTj,表示j jj号函数的类型:

  1. T j = 1 T_j = 1Tj=1,接下来两个整数P j , V j P_j, V_jPj,Vj分别表示要执行加法的元素的下标及其增加的值;
  2. T j = 2 T_j = 2Tj=2,接下来一个整数V j V_jVj表示所有元素所乘的值;
  3. T j = 3 T_j = 3Tj=3,接下来一个正整数C j C_jCj表示j jj号函数要调用的函数个数,
    随后C j C_jCj个整数g 1 ( j ) , g 2 ( j ) , … , g C j ( j ) g^{(j)}_1, g^{(j)}_2, \ldots , g^{(j)}_{C_j}g1(j),g2(j),,gCj(j)依次表示其所调用的函数的编号。

m + 4 m + 4m+4行一个正整数Q QQ,表示输入的函数操作序列长度。
m + 5 m + 5m+5Q QQ个整数f i f_ifi,第i ii个整数表示第i ii个执行的函数的编号。

【输出】

一行n nn个用空格隔开的整数,按照下标1 ∼ n 1 \sim n1n的顺序,分别输出在执行完输入的函数序列后,数据库中每一个元素的值。答案对998244353 \boldsymbol{998244353}998244353取模。

【输入样例】

3 1 2 3 3 1 1 1 2 2 3 2 1 2 2 2 3

【输出样例】

6 8 12

【算法标签】

#提高+# #拓扑排序#

【代码详解】

#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=200005,mod=998244353;// 函数结构体,表示每个操作structFunc{intop,p,v;// op: 操作类型, p: 位置参数, v: 值参数}func[N];// 边结构体,表示图的边structEdge{intv,w;// v: 目标节点, w: 边权};intn,m,q;// n: 初始变量数量, m: 操作数量, q: 查询数量intmul[N];// 乘法因子,表示从该节点开始的累积乘积intans[N];// 最终答案数组intin[N];// 入度数组,用于拓扑排序intp[N];// 系数数组,表示每个节点对最终结果的贡献系数vector<Edge>adj[N];// 邻接表,表示有向图// 递归计算从节点u开始的累积乘积intinit(intu){if(mul[u]!=-1||adj[u].empty())// 如果已经计算过或者是叶子节点{returnmul[u];}mul[u]=1;// 初始化为1// 递归计算所有后继节点的乘积for(inti=0;i<adj[u].size();i++){intv=adj[u][i].v;mul[u]=mul[u]*init(v)%mod;}returnmul[u];}// 计算每条边的权重voidwork(){for(intu=0;u<=n+m;u++)// 遍历所有节点{intr=1;// 从右向左的累积乘积// 从后向前遍历邻接表for(inti=adj[u].size()-1;i>=0;i--){intv=adj[u][i].v;adj[u][i].w=r;// 设置边的权重为右侧的累积乘积r=r*mul[v]%mod;// 更新累积乘积}}}// 拓扑排序,计算每个节点的贡献系数voidtopo(){queue<int>q;// 用于拓扑排序的队列p[0]=1;// 起点节点的系数为1// 将所有入度为0的节点加入队列for(inti=0;i<=n+m;i++){if(in[i]==0){q.push(i);}}// 拓扑排序主循环while(!q.empty()){intu=q.front();q.pop();// 遍历u的所有出边for(inti=0;i<adj[u].size();i++){intv=adj[u][i].v;intw=adj[u][i].w;// 更新后继节点的系数p[v]=(p[v]+w*p[u]%mod)%mod;in[v]--;// 减少入度// 如果入度变为0,加入队列if(in[v]==0){q.push(v);}}}}signedmain(){memset(mul,-1,sizeof(mul));// 初始化mul数组为-1// 第一部分:输入初始变量cin>>n;for(inti=1;i<=n;i++){cin>>func[i].v;// 输入初始值func[i].op=1;// 操作类型1:赋值func[i].p=i;// 赋值位置mul[i]=1;// 乘法因子为1in[i]++;// 增加入度adj[0].push_back({i,0});// 从0节点连接到i节点}// 第二部分:输入操作cin>>m;for(inti=n+1;i<=m+n;i++){cin>>func[i].op;// 输入操作类型if(func[i].op==1)// 操作类型1:赋值{cin>>func[i].p>>func[i].v;// 输入位置和值mul[i]=1;// 乘法因子为1}elseif(func[i].op==2)// 操作类型2:乘法{cin>>func[i].v;// 输入乘数mul[i]=func[i].v;// 乘法因子为v}else// 操作类型3:函数调用{intc,g;cin>>c;// 输入参数个数for(intj=1;j<=c;j++){cin>>g;// 输入每个参数adj[i].push_back({g+n,0});// 添加边in[g+n]++;// 增加入度}}}// 第三部分:输入查询cin>>q;for(intj=1;j<=q;j++){intf;cin>>f;// 输入查询的函数adj[0].push_back({f+n,0});// 从0节点连接到查询函数in[f+n]++;// 增加入度}// 第四部分:计算和处理init(0);// 从0节点开始计算累积乘积work();// 计算边权topo();// 拓扑排序,计算系数// 第五部分:计算结果for(inti=1;i<=n+m;i++){if(func[i].op==1)// 如果是赋值操作{// 将值乘以系数,累加到对应位置ans[func[i].p]=(ans[func[i].p]+func[i].v*p[i]%mod)%mod;}}// 输出结果for(inti=1;i<=n;i++){cout<<ans[i]<<" ";}cout<<endl;return0;// 程序正常结束}

【运行结果】

3 1 2 3 3 1 1 1 2 2 3 2 1 2 2 2 3 6 8 12
http://www.jsqmd.com/news/714924/

相关文章:

  • 3大核心功能解密:OpenCore Legacy Patcher如何让老旧Mac重获新生
  • CSS如何使得响应式的侧边抽屉附带遮罩渐暗效果
  • 2026年一体化预制泵站/污水提升泵站/一体式泵站实力厂家推荐:聚焦技术领先与多场景应用方案 - 泵站报价15613348888
  • 绵阳老房翻新选对公司,千川环宇帮你实现安全焕新 - 资讯焦点
  • VS Code Copilot Next 成本失控真相(2024 Q2真实账单拆解):从$287→$49/月的7类配置陷阱与修复清单
  • 2026年宁波短视频代运营与GEO优化:中小企业同城获客完全指南 - 优质企业观察收录
  • 橱柜小拉手优质厂家盘点:精选五家实力生产商推荐指南 - 品牌策略师
  • 2026年度中国房车定制游服务商综合实力TOP6推荐 - 资讯焦点
  • Omdia:2025年第四季度,中国大陆云基础设施支出增长26%,AI与智能体成主要驱动力
  • 【网络协议-10】低成本物联网产品放弃SSL加密的隐形成本与市场逻辑
  • 从零开始:手把手教你跑通、分析和“解剖”大模型
  • 深度技术解析:Windows系统工具注册表权限管理完整指南
  • 让 Claude Code : Codex: Open Code 成本爆降 92%,没早用上这款开源工具。。。
  • 可替代进口频谱分析仪推荐:安徽白鹭电子实力诠释国产崛起 - 品牌推荐大师
  • 上海强平机器人官方联系方式合作电话官方网站官网 - 资讯焦点
  • 别再死记硬背了!用这5个Mathf函数搞定Unity角色移动与旋转(附完整代码)
  • 用Verilog和DAC芯片手把手教你做个可编程波形发生器(附完整RTL代码与示波器实测)
  • 【VS Code MCP插件生态搭建权威指南】:20年IDE架构师亲授5大核心配置步骤与3个避坑红线
  • 从传感器配置到标签解析:一份给研究者的RADIal数据集深度使用指南
  • 广州市黄埔区鑫邦租赁:广州二手空压机回收推荐哪几家 - LYL仔仔
  • Biosimilar抗体选购:TargetMol保障高特异性 - 资讯焦点
  • LeetCode HOT100 - 无重复字符的最长子串
  • 告别动画蓝图复杂连线!在UE5里用Control Rig模块化重构你的Foot IK系统(含GitHub工程对比)
  • Win11Debloat:Windows系统优化与隐私保护解决方案的技术实现
  • palera1n越狱工具终极指南:解锁A8-A11设备的iOS 15+系统限制
  • Phi-mini-MoE-instruct快速上手:3步启动http://localhost:7860对话界面
  • 2026年宁波短视频代运营与GEO搜索优化:5大服务商深度横评与选购指南 - 优质企业观察收录
  • 节假日生日宴菜单实测:全龄适配的粤赣融合宴请方案 - 资讯焦点
  • C++27范围算法提速47%?实测std::ranges::sort_stable与chunk_by_exhaustive,现代迭代器协议重构真相大起底,
  • 从安防到健身APP:聊聊人体姿态估计(Pose Estimation)技术落地的那些事儿