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下栈是向低地址扩展的数据结构,是一块连续的内存区域.这句话的意思是栈顶的地址和栈的最大容量是系统预 ...
随机推荐
- ip_rcv 中使用skb_share_check
/* * Main IP Receive routine. */ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct pack ...
- GC 的认识(转) https://github.com/qcrao/Go-Questions/blob/master/GC/GC.md#1-什么是-gc有什么作用
1. 什么是 GC,有什么作用? GC,全称 Garbage Collection,即垃圾回收,是一种自动内存管理的机制. 当程序向操作系统申请的内存不再需要时,垃圾回收主动将其回收并供其他代码进行内 ...
- (2)ElasticSearch在linux环境中集成IK分词器
1.简介 ElasticSearch默认自带的分词器,是标准分词器,对英文分词比较友好,但是对中文,只能把汉字一个个拆分.而elasticsearch-analysis-ik分词器能针对中文词项颗粒度 ...
- C#高级编程之泛型一(泛型的引入、泛型的使用、何为泛型)
为何引入泛型 当我们要对不同类型的参数执行类似的方法时:如下所示功能打印传入参数的相关信息. class CommonMethdod { /// <summary> /// show in ...
- C语言中的const用法
Const是什么? const是一个C语言的关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程 ...
- SHEIN:Java开发面经
SHEIN面经 我觉得除技术外,自信是一个非常关键的点. 一面 自我介绍: 谈谈实习经历: 讲讲你实习的收获: 如何设计规范的接口?(简历上有写,所以问到) 当你需要修改两个月前的代码时,如何去整理以 ...
- cdh中jps显示process information unavailable问题的解决
百度的方法有两种: 第一种 1.进入/tmp 2.删除该目录下的hsperfdata_${username} 文件夹 3.再执行jps 第二种 做软连接 或者修改权限hsperfdata_${user ...
- vue的html2canvas将dom转化为图片时踩得坑
一.html2canvas中图片涉及跨域图片 应用场景:做个投票活动,将参赛者的信息转化成图片截图分享.用户上传图片上传到腾讯云cos桶中,html2canvas只能转换本地资源的图片,涉及跨域的图片 ...
- 这次齐了!Java面向对象、类的定义、对象的使用,全部帮你搞定
概述 Java语言是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想,我们在面向对象思想的指引下, 使用Java语言去设计.开发计算机程序. 这里的对象泛指现实中一切事物,每种事物都具备自 ...
- 如何用MathType 7输入x的一阶导数
物理学.几何学.经济学等学科中的一些重要概念都可以用导数来表示.如,导数可以表示运动物体的瞬时速度和加速度.可以表示曲线在一点的斜率.还可以表示经济学中的边际和弹性.那么作为专业的公式编辑器,如何输入 ...