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下栈是向低地址扩展的数据结构,是一块连续的内存区域.这句话的意思是栈顶的地址和栈的最大容量是系统预 ...
随机推荐
- 位图bitmap应用
所有比特的编号方法是,从低字节的低位比特位开始,第一个bit为0,最后一个bit为 n-1. 比如说,现在有个数组是这样子的,int a[4],那么a[0]的比特位为0--31a[1]的比特位为32- ...
- 缩点Tarjan算法解析+[题解]受欢迎的牛
(注:我在网上找了一些图,希望原博主不要在意,谢谢,(。☉౪ ⊙。)) 首先来了解什么是强连通分量 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向 ...
- HTTP 报文格式简介
HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送 WWW 方式的数据,关于 HTTP 协议的详细内容请参考 RFC2616.HTTP 协议采用了请求/响 ...
- Linux 中deb文件选择安装路径
deb文件安装后默认目录在/usr**中如果想指定自定义安装目录 选择自定义目录 sudo dpkg -i --instdir=/to/your/customer/path ***.deb 软连接创建 ...
- [原题复现]-HITCON 2016 WEB《babytrick》[反序列化]
前言 不想复现的可以访问榆林学院信息安全协会CTF训练平台找到此题直接练手 HITCON 2016 WEB -babytrick(复现) 原题 index.php 1 <?php 2 3 inc ...
- C++中new和malloc区别
面试中new和malloc区别会被经常问到,审视了自己,发现不知道该怎么表达 整理一下: 1.从属性 new/delete是C++关键字,需要编译器支持: malloc/free是库函数,需要头文件支 ...
- 为什么换了电脑安装MindManager提示密钥失效?
相信很多MindManager用户遇到过这样的问题,不想在原电脑上使用MindManager思维导图软件,想要换电脑安装,但是提示该许可证密钥失效了.下面文章就教大家如何解决这个问题: 我们在Mind ...
- centons 7 清机 脚本
#/bin/bash##################################初始化系统###################setenforce 0 yum install -y yum- ...
- yii的pathinfo方式实现
yii2.0在浏览器中默认查看控制器下的方法是 http://ltbk.cn/index.php?r=login/login 要是在浏览器上输出 http://ltbk.cn/index.php/l ...
- 自学linux——12.shell进阶
Shell进阶 当把在Windows中写好的脚本传到linux中使用时,在Windows下每一行结尾是\n\r,而Linux下则是\n,所以会多出来\r,在linux中运行脚本时,需执行: sed - ...