P7077 [CSP-S2020] 函数调用
时间:2021-07-25
本文章向大家介绍P7077 [CSP-S2020] 函数调用,主要包括P7077 [CSP-S2020] 函数调用使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
预处理出函数 \(i\) 乘上的系数 \(mul_i\),显然函数之间的调用关系形成了一张拓扑图。
不妨将整个程序视为一个类型 \(3\) 的函数,从其开始拓扑排序。记 \(k_i\) 表示位置 \(i\) 当前加上的数,\(f_i\) 表示函数 \(i\) 当前对其中加法函数的调用次数。
注意到一个加法函数产生的贡献只取决于加数和调用次数,后者我们可以通过累加的方式来得到;一个
- 类型 \(1\)。此后再也不会调用它了,那么它的贡献可以算好了:\(k_{P_i}\gets k_{P_i}+V_i\times f_i\)。
- 类型 \(2\)。其贡献在 \(mul\) 中,直接忽略。
- 类型 \(3\)。因为前面的乘法能影响到后面的加法,所以考虑倒序遍历。
函数 \(i\) 调用了函数 \(j\):\(f_j\gets f_j+f_i,f_i\gets f_i\times mul_j\)。
注意没出现过的函数要删掉出边以免影响拓扑排序。时间复杂度 \(O(n)\)。
code:
#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define NN 1000005
#define Mod 998244353
#define For(i,x,y)for(i=x;i<=(y);i++)
struct node
{
int next,to;
}e[2000005];
bool vis[NN];
queue<int>que;
int head[NN],p[NN],val[NN],t[NN],mul[NN],deg[NN],f[NN],a[N],k[N],g;
int read()
{
int A;
bool K;
char C;
C=A=K=0;
while(C<'0'||C>'9')K|=C=='-',C=getchar();
while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar();
return(K?-A:A);
}
inline void add(int u,int v)
{
e[++g].to=v;
e[g].next=head[u];
head[u]=g;
}
void dfs(int u)
{
if(vis[u])return;
int v,i;
vis[u]=1;
if(t[u]==2)mul[u]=val[u];
else if(t[u]==3)
{
mul[u]=1;
for(i=head[u];i;i=e[i].next)
{
v=e[i].to;
dfs(v);
mul[u]=1LL*mul[u]*mul[v]%Mod;
}
}
else mul[u]=1;
}
int main()
{
// freopen("call.in","r",stdin);
// freopen("call.out","w",stdout);
int n,i,m,c,x,u,v,q;
n=read();
For(i,1,n)a[i]=read();
m=read();
For(i,1,m)
{
t[i]=read();
if(t[i]==1)p[i]=read(),val[i]=read();
else if(t[i]==2)val[i]=read();
else
{
c=read();
while(c--)
{
x=read();
add(i,x);
deg[x]++;
}
}
}
t[++m]=3;
q=read();
while(q--)
{
x=read();
add(m,x);
deg[x]++;
}
mul[m]=f[m]=1;
dfs(m);
For(u,1,m)
if(!vis[u])
for(i=head[u];i;i=e[i].next)deg[e[i].to]--;
que.push(m);
while(!que.empty())
{
u=que.front();
que.pop();
if(t[u]==1)k[p[u]]=(k[p[u]]+1LL*val[u]*f[u])%Mod;
else if(t[u]==3)
for(i=head[u];i;i=e[i].next)
{
v=e[i].to;
deg[v]--;
if(!deg[v])que.push(v);
/*printf("%d %d\n",u,v);*/
f[v]=(f[v]+f[u])%Mod;
f[u]=1LL*f[u]*mul[v]%Mod;
}
}
For(i,1,n)printf("%d ",(1LL*a[i]*mul[m]+k[i])%Mod);
return 0;
}
原文地址:https://www.cnblogs.com/May-2nd/p/14989767.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android studio实现滑动开关
- Android实现TCP客户端支持读写操作
- Android通过命令连接wifi的方法(解决usb不能用问题)
- android studio使用SQLiteOpenHelper()建立数据库的方法
- Android自定义View绘制彩色圆弧
- android canvas使用line画半圆
- 说说Android的UI刷新机制的实现
- Android仿直播类app赠送礼物功能
- android自定义imageview实现圆角图片
- 基于android实现五子棋开发
- Android Fragment的静态注册和动态注册创建步骤
- Android从Fragment跳转到其他Activity的简单实例
- Android7.0以上Uri转路径的方法实现(已验证)
- Android studio实现简单计算器
- Android 自定义LayoutManager实现花式表格