zoukankan      html  css  js  c++  java
  • [CSP-S2020] 函数调用

    前言

    陈年旧账。

    题目

    洛谷

    讲解

    我们需要将这三种函数之间的互相影响的关系找出来。

    可以发现操作一是最基础的,所以我们可以以此来计算贡献。

    考虑操作二对操作一的影响,发现影响范围前面所有的操作一,显然我们需要逆序做。假如是乘 (mul),那么相当于操作一执行 (mul) 次,这个思想比较关键。

    考虑操作三调用了很多复杂函数,但由于我们只考虑对操作一的影响,所以还是从后往前记录操作二的乘积,往前有操作一的时候乘上这个记录的值即可,相当于逆序求出操作一执行次数。

    具体实现可以将 (0) 号点向操作序列连边,提前处理一下每个函数会将整体乘上多少,然后在 DAG 上拓扑排序即可。

    代码

    说实话,挺短
    //12252024832524
    #include <bits/stdc++.h>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 100005;
    const int MOD = 998244353; 
    int n,m;
    int a[MAXN],mul[MAXN],add[MAXN],pos[MAXN],cnt[MAXN],deg[MAXN]; 
    
    LL Read()
    {
    	LL x = 0,f = 1; char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    vector<int> G[MAXN];
    
    bool vis[MAXN];
    void dfs(int x)
    {
    	vis[x] = 1;
    	for(auto v : G[x]) 
    	{
    		if(!vis[v]) dfs(v);
    		mul[x] = 1ll * mul[x] * mul[v] % MOD;
    	}
    }
    void topu()
    {
    	queue<int> q;
    	for(int i = 0;i <= m;++ i) if(!deg[i]) q.push(i);
    	while(!q.empty())
    	{
    		int x = q.front(),now = 1; q.pop();
    		reverse(G[x].begin(),G[x].end());
    		for(auto v : G[x])
    		{
    			cnt[v] = (cnt[v] + 1ll * cnt[x] * now) % MOD;
    			now = 1ll * now * mul[v] % MOD;
    			if(!(--deg[v])) q.push(v);
    		}
    	}
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read();
    	for(int i = 1;i <= n;++ i) a[i] = Read();
    	m = Read();
    	for(int i = 1;i <= m;++ i)
    	{
    		int opt = Read(); mul[i] = 1;
    		if(opt == 1) pos[i] = Read(),add[i] = Read();
    		else if(opt == 2) mul[i] = Read();
    		else 
    		{
    			int k = Read();
    			for(int j = 0,v;j < k;++ j)
    			{
    				v = Read();
    				G[i].emplace_back(v);
    				++deg[v];
    			}
    		}
    	}
    	mul[0] = cnt[0] = 1;
    	for(int Q = Read(); Q ;-- Q)
    	{
    		int v = Read();
    		G[0].emplace_back(v);
    		++deg[v];
    	}
    	for(int i = 0;i <= m;++ i) if(!vis[i]) dfs(i);
    	topu();
    	for(int i = 1;i <= n;++ i) a[i] = 1ll * a[i] * mul[0] % MOD;
    	for(int i = 1;i <= m;++ i)
    		if(pos[i]) a[pos[i]] = (a[pos[i]] + 1ll * cnt[i] * add[i]) % MOD;
    	for(int i = 1;i <= n;++ i) Put(a[i],' ');
    	return 0;
    }
    
  • 相关阅读:
    python路径相关
    python之json
    python之正则表达式备忘
    MD5 SHA1 HMAC HMAC_SHA1区别
    微信根据openid给用户发送图文消息
    最近做的几个小程序
    5000万pv小程序,高并发及缓存优化,入坑
    小程序 后台发送模板消息
    mysql 组合索引
    php 拆分txt小说章节保存到数据库
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/15438034.html
Copyright © 2011-2022 走看看