• [CSP-S-2 2020 T3] 函数调用 (拓扑排序)


    [CSP-S 2020 T3] 函数调用 (拓扑排序)

    updated: 之前标题好像搞成T2的标题了。。

    很难考虑每个操作的顺序,但由于操作比较简单,可以直接考虑每个操作贡献的权值

    一个操作的权值可以定义为:每次这个操作执行之后后,后面所有的乘法操作的积

    如果没有递归,只需要倒序枚举一次调用情况,就能知道所有的权值

    对于递归的情况,显然函数之间的递归关系构成一张拓扑图,可以考虑预处理出每个操作的乘法操作之积

    对于所有的函数,同样能得到一个权值,接下来的操作只需要把每个存在递归的函数不断将权值向下传给子函数

    如果把最终的调用序列看做一个主函数,那么对于这个操作实际也是一样的做法

    即:倒序枚举一次累积,然后乘上自己的权值下传即可

    Tips: 最后加入贡献时,注意先将所有数的权值乘上全局乘法倍数,然后再依次处理每个加法操作

    #include<bits/stdc++.h>
    using namespace std;
    
    #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
    
    char IO;
    int rd(){ 
    	int s=0,f=0;
    	while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    	do s=(s<<1)+(s<<3)+(IO^'0');
    	while(isdigit(IO=getchar()));
    	return f?-s:s;
    }
    
    const int N=1e5+10,P=998244353;
    
    int n,m;
    int A[N],T[N],H[N]; 
    // A为原数组,T为乘法积,H为函数调用权值
    int O[N],X[N],Y[N];
    int B[N*11],C,L[N],R[N],ind[N];
    int Q[N],QL,QR;
    
    int main() {
    	//freopen("call.in","r",stdin),freopen("call.out","w",stdout);
    	rep(i,1,n=rd()) A[i]=rd();
    	m=rd()+1; // 令m+1号为主函数
    	rep(i,1,m) {
    		O[i]=i<m?rd():3,T[i]=1;
    		if(O[i]==1) X[i]=rd(),Y[i]=rd();
    		else if(O[i]==2) T[i]=rd();
    		else {
    			L[i]=C+1,R[i]=C+=rd();
    			rep(j,L[i],R[i]) ind[B[j]=rd()]++;
    		}
    	}
    	rep(i,QL=1,m) if(!ind[i]) Q[++QR]=i;
    	while(QL<=QR) {
    		int u=Q[QL++];
    		if(O[u]==3) rep(j,L[u],R[u]) if(--ind[B[j]]==0) Q[++QR]=B[j];
    	}
    	drep(k,m,1){
    		int u=Q[k];
    		if(O[u]==3) rep(j,L[u],R[u]) T[u]=1ll*T[u]*T[B[j]]%P;
    	}
    	
    	rep(i,H[m]=1,n) A[i]=1ll*A[i]*T[m]%P;
    	rep(k,1,m) {
    		int u=Q[k],x=1;
    		drep(j,R[u],L[u]){
    			int v=B[j];
    			H[v]=(H[v]+1ll*x*H[u])%P;
    			x=1ll*x*T[v]%P;
    		}
    		if(O[u]==1) A[X[u]]=(A[X[u]]+1ll*H[u]*Y[u])%P;
    	}
    	rep(i,1,n) printf("%d ",A[i]); puts("");
    }
    
  • 相关阅读:
    创建数据库指定编码格式
    java开发环境配置
    Eclipse 配置工程
    声明式事务管理 的5 种方式
    web容器启动顺序
    2.1 实践篇:使用ping来检测网速
    1.1 mysql安装
    1.2 测试人员与开发人员比例
    1.0 软件测试能力
    1.4 测试各阶段(单元、集成、系统 、Alpha、Beta、验收)
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13944599.html
Copyright © 2020-2023  润新知