P7077 函数调用
我好蠢啊。。。
考试的时候不会写,现在看了这么多篇题解还是似懂非懂,所以决定写一下草稿。。。
草稿 和 题解
就是首先,题目保证了函数不会间接的调用其本身,所以可以直接知道这是一个 \(\text{DAG}\) ,从这个角度去考虑。
然后我们考虑对于两种操作,乘法的操作最后乘一下即可,但是对于加法操作,我们需要知道其之后的乘法对于自己的贡献。
因为要保证复杂度,所以这个东西是不能多次 \(\text{top}\) 来维护的。所以我们考虑如何在 \(\text{DAG}\) 上直接搞这个玩意儿。
我们可以先在每个节点处理出来如果选择他,你可以给后面的节点贡献多少的系数。这个东西一个 \(\text{top}\) 即可。然后可以考虑从后往前更新,用一个变量来维护到目前为止,你已经给整一个全局贡献了多少的变量,然后对于每一个点,在其前面进行的乘法操作也是需要考虑的。
最后再进行一次 \(\text{top}\) 将每个点的系数下传一下,下传的方法和之前类似,同时统计一下加法操作的贡献就可以了。
终于明白了!!!
感悟
高妙,高妙!
感觉自己对于 \(\text{top}\) 排序的理解都加深了。感觉跟有一些 \(\text{DP}\) 的思路有一点像,我们将贡献后置,然后再依次推出当前的系数是多少。
高妙,高妙!
代码
#include<bits/stdc++.h>
using namespace std;
#define Lint long long
inline int read()
{
	char c=getchar();int x=0;
	while(c<'0'||c>'9') c=getchar();
	while('0'<=c&&c<='9') x=x*10+c-'0',c=getchar();
	return x;
}
const int N=1e5+5,M=1e5+5,Q=1e5+5,E=1e6+5;
const Lint MOD=998244353;
int n,m;Lint a[N];int c[Q];
struct Point{Lint mul,coe,add;int tag,pos;}b[M];
struct Edge{int nxt,to;}e[2][E];int fir[2][M],deg[M],size[2];
void add(int u,int v,int tag){e[tag][++size[tag]]=(Edge){fir[tag][u],v},fir[tag][u]=size[tag];}
queue<int> q;
int topn[N],cnt=0;
void top()
{
	for(int i=1;i<=m;++i) if(deg[i]==0) q.push(i);
	while(!q.empty())
	{
		int tmp=q.front();q.pop();
		topn[++cnt]=tmp;
		for(int i=fir[0][tmp];i;i=e[0][i].nxt)
		{
			deg[e[0][i].to]--;
			if(!deg[e[0][i].to]) q.push(e[0][i].to);
		}
	}
}
int opt[Q];
int main()
{
//	freopen("call.in","r",stdin);
//	freopen("call.out","w",stdout);
	n=read();
	for(int i=1;i<=n;++i) a[i]=read();
	m=read();
	for(int i=1;i<=m;++i)
	{
		b[i].tag=read(),b[i].mul=1;
		if(b[i].tag==1) b[i].pos=read(),b[i].add=read();
		if(b[i].tag==2) b[i].mul=read();
		if(b[i].tag==3)
		{
			deg[i]=read();
			for(int j=1,v;j<=deg[i];++j)
			v=read(),add(v,i,0),add(i,v,1);
		}
	}
	top();
	for(int i=1;i<=m;++i)
	{
		for(int j=fir[0][topn[i]];j;j=e[0][j].nxt)
		b[e[0][j].to].mul*=b[topn[i]].mul,b[e[0][j].to].mul%=MOD;
	}
	int q=read();
	for(int i=1;i<=q;++i) c[i]=read();
	Lint now=1;
	for(int i=q;i>=1;--i)
	{
		b[c[i]].coe+=now,b[c[i]].coe%=MOD;
		now*=b[c[i]].mul,now%=MOD;
	}
	for(int i=1;i<=n;++i) a[i]*=now,a[i]%=MOD;
	for(int i=m;i>=1;--i)
	{
		Lint now=1;
		for(int j=fir[1][topn[i]];j;j=e[1][j].nxt)
		{
			b[e[1][j].to].coe+=b[topn[i]].coe*now%MOD,b[e[1][j].to].coe%=MOD;
			now*=b[e[1][j].to].mul,now%=MOD;
		}
	}
	for(int i=1;i<=m;++i)
	{
		if(b[i].tag==1)
		a[b[i].pos]+=b[i].add*b[i].coe%MOD,a[b[i].pos]%=MOD;
	}
	for(int i=1;i<=n;++i) printf("%lld ",a[i]);
	printf("\n");
	return 0;
}
												
											P7077 函数调用的更多相关文章
- idapython实现动态函数调用批量注释
		
部门小伙伴遇到一个样本需要对动态函数调用就行批量注释还原的问题,通过idapython可以大大的减少工作量,其实这一问题也是很多样本分析中最耗时间的一块,下面来看看如何解决这个问题(好吧这才是今年最后 ...
 - [汇编与C语言关系]1.函数调用
		
对于以下程序: int bar(int c, int d) { int e = c + d; return e; } int foo(int a, int b) { return bar(a, b); ...
 - javascript函数调用的各种方法!!
		
在JavaScript中一共有下面4种调用方式: (1) 基本函数调用 (2)方法调用 (3)构造器调用 (4)通过call()和apply()进行调用 1. 基本函数调用 普通函数调用模式,如: J ...
 - jsContext全局函数调用与对象函数调用、evaluateScript
		
evaluateScript:兼具js加载(生成具体的上下文)(函数与通用变量的加载),与函数执行的功能: 函数调用的方式有两种: 1)获取函数(对象),然后执行调用: [context[@" ...
 - 用 Graphviz+pvtrace 可视化函数调用
		
最近在想怎么把一个程序的函数调用关系快速的用流程图的方式画出来,之后看到了这个一篇文章“用 Graphviz 可视化函数调用”(http://www.ibm.com/developerworks/cn ...
 - 行内js函数调用
		
<ul> <li onclick=abc(this);><a href="javascript:void(0);">12234588</a ...
 - ObReferenceObjectByName函数调用WIN7下的解决
		
<寒江独钓 Windows内核安全编程>第4章键盘的过滤ctrl2cap代码中,ObReferenceObjectByName函数调用: [1]extern POBJECT_TYPE Io ...
 - c语言函数, 函数调用及函数递归
		
1. 函数的定义: 返回值类型 函数名(形参列表) {函数体(函数的实现内容)}, 注意: 如果没有参数, 小括号也是必不可少的. 函数与函数之间可以嵌套调用(也就是在一个函数内部可以调用另外一个函 ...
 - C/C++函数调用的几种方式及函数名修饰规则以及c++为什么不允许重载仅返回类型不同的函数
		
我们知道,调用函数时,计算机常用栈来存放函数执行需要的参数,由于栈的空间大小是有限的,在windows下栈是向低地址扩展的数据结构,是一块连续的内存区域.这句话的意思是栈顶的地址和栈的最大容量是系统预 ...
 
随机推荐
- 线程队列分享ppt
 - TTL门和MOS门悬空输入的处理
			
引言 本来是数字电路学习时很重要的考点,但是总容易忘掉,所以记录一下~ 内容 TTL TTL电路中的TTL是Transistor-Transistor-Logic的英文缩写,指的是晶体管逻辑电路,即T ...
 - 《.NET 5.0 背锅案》第6集-案发现场回顾:故障情况下 Kubernetes 的部署表现
			
第1集:验证 .NET 5.0 正式版 docker 镜像问题 第2集:码中的小窟窿,背后的大坑,发现重要嫌犯 EnyimMemcachedCore 第3集-剧情反转:EnyimMemcachedCo ...
 - 接口自动化测试:apiAutoTest使用re 处理数据依赖
			
目录 废话 2020/11/19 参数依赖 更新后的效果 新版依赖数据如何使用 源码地址 道谢 废话 目前在工作中写脚本的时候发现了一些之前开源的apiAutoTest的可优化项,后面应该也是会慢慢的 ...
 - kali ms17_010 内网环境下渗透笔记
			
一.先用Router Scan 扫描 看清楚了网络拓扑结构. 二.使用MS17-010批量扫描工具 下载:ms17-010Scan.exe (也可以用kali自带的nmap和ms17-10模块扫) ...
 - FL Studio通道窗口和步进音序器知识讲解
			
FL Studio中通道窗口是以样本为概念的音乐制作基础.通道窗口包含了步进音序器并结合了各种丰富的功能,可以通过通道窗口打开各通道的设置窗口.钢琴卷轴等.步进音序器在节奏制作方便表现出很好的优势,它 ...
 - yii2.0 模态框简单使用
			
1 <?php foreach($data as $model) :?> 2 3 <!-- 按钮触发模态框 --> 4 <button class="btn b ...
 - JAVA 中的Optional (臭名昭著的空指针异常(NullPointerException))
			
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...
 - Linux安装MySQL5.7(CentOS)
			
1.下载解压 1.1 MySql 5.7.26下载地址: https://dev.mysql.com/downloads/mysql/5.7.html#downloads 1.2 解压 tar -xv ...
 - Matlab 数组
			
数组创建 1:逐个元素输入法:如:x=[1 2 3 4 5](中间也可以用逗号隔开) 2:冒号法:如:x=1:1:5 %从1到5步长为1 3:linspace 法: ----创建线性等距的数组 lin ...