列表

详情


NC213856. [CSP2020]函数调用(call)

描述

题目数据为官方数据,可以提交测试,结果仅供参考,不代表官方成绩,最终成绩以官方发布的最终成绩为准。


函数是各种编程语言中一项重要的概念,借助函数,我们总可以将复杂的任务分解成一个个相对简单的子任务,直到细化为十分简单的基础操作,从而使代码的组织更加严密、更加有条理。然而,过多的函数调用也会导致额外的开销,影响程序的运行效率。
某数据库应用程序提供了若干函数用以维护数据。已知这些函数的功能可分为三类:
  1. 将数据中的指定元素加上一个值;
  2. 将数据中的每一个元素乘以一个相同值;
  3. 依次执行若干次函数调用,保证不会出现递归(即不会直接或间接地调用本身)。

在使用该数据库应用时,用户可一次性输入要调用的函数序列(一个函数可能被调用多次),在依次执行完序列中的函数后,系统中的数据被加以更新。某一天,小 A 在应用该数据库程序处理数据时遇到了困难:由于频繁而低效的函数调用,系统在执行操作时进入了无响应的状态,他只好强制结束了数据库程序。为了计算出正确数据,小 A 查阅了软件的文档,了解到每个函数的具体功能信息,现在他想请你根据这些信息帮他计算出更新后的数据应该是多少。

输入描述

第  行一个正整数 ,表示数据的个数。
第  行  个整数,第  个整数表示下标为  的数据的初始值为 
第  行一个正整数 ,表示数据库应用程序提供的函数个数。函数从  编号。
接下来  行中,第 行的第一个整数为 ,表示  号函数
的类型:

1.若 ,接下来两个整数  分别表示要执行加法的元素的下标及其增加的值;
2.若 ,接下来一个整数  表示所有元素所乘的值;
3.若 ,接下来一个正整数 𝐶_𝑗 表示  号函数要调用的函数个数,随后  个整数  依次表示其所调用的函数的编号。

第  行一个正整数 ,表示输入的函数操作序列长度。
第  行  个整数 ,第  个整数表示第  个执行的函数的编号。

输出描述

一行  个用空格隔开的整数,按照下标  的顺序,分别输出在执行完输入的函数序列后,数据库中每一个元素的值。答案对 998244353 取模

示例1

输入:

3
1 2 3
3
1 1 1
2 2
3 2 1 2
2
2 3

输出:

6 8 12

说明:

1 号函数功能为将  的值加一。2 号函数功能为所有元素乘 2。3 号函数将先调用 1 号函数,再调用 2 号函数。
最终的函数序列先执行 2 号函数,所有元素的值变为 2,4,6。
再执行 3 号函数时,先调用 1 号函数,所有元素的值变为3,4,6。再调用 2 号函数,所有元素的值变为 6,8,12。

示例2

输入:

10
1 2 3 4 5 6 7 8 9 10
8
3 2 2 3
3 2 4 5
3 2 5 8
2 2
3 2 6 7
1 2 5
1 7 6
2 3
3
1 2 3

输出:

36 282 108 144 180 216 504 288 324 360

说明:

对于所有数据:𝑇_𝑗 ∈ \{1,2,3\}, 

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 99ms, 内存消耗: 16368K, 提交时间: 2023-08-05 14:40:40

#include <bits/stdc++.h>
using namespace std;

#define ll long long
inline ll read(){
	ll x=0,sign=0; char s=getchar();
	while(s>'9'||s<'0')sign|=s=='-',s=getchar();
	while(s<='9'&&s>='0')x=(x<<1)+(x<<3)+s-'0',s=getchar();
	return sign?-x:x;
}

const int N=1e5+5;
const int mod=998244353;

int n,m,c,a[N],deg[N],func[N];
int tp[N],pos[N],val[N];
ll mu=1,mul[N],dp[N],add[N];
vector <int> e[N];
queue <int> q;

bool vis[N];
void dfs(int id){
	vis[id]=1,mul[id]=(tp[id]==2?val[id]:1);
	for(int it:e[id]){
		if(!vis[it])dfs(it);
		mul[id]=mul[id]*mul[it]%mod;
	}
}

int main(){
	n=read(); for(int i=1;i<=n;i++)a[i]=read();
	m=read();
	for(int i=1;i<=m;i++){
		tp[i]=read();
		if(tp[i]==1)pos[i]=read(),val[i]=read();
		else if(tp[i]==2)val[i]=read();
		else{
			c=read();
			while(c--){
				int to=read();
				e[i].push_back(to),deg[to]++;
			}
		}
	} c=read();
	for(int i=1;i<=m;i++)if(!vis[i]&&!deg[i])dfs(i);
	for(int i=1;i<=c;i++)func[i]=read();
	for(int i=c,f=func[i];i;i--,f=func[i]){
		if(tp[f]==1)dp[f]=(dp[f]+mu);
		else if(tp[f]==2)mu=mu*val[f]%mod;
		else dp[f]=(dp[f]+mu),mu=mu*mul[f]%mod;
	} for(int i=1;i<=m;i++)if(!deg[i])q.push(i);
	while(!q.empty()){
		int t=q.front(); q.pop();
		if(tp[t]==1)add[pos[t]]=(add[pos[t]]+dp[t]*val[t])%mod;
		ll z=dp[t]; reverse(e[t].begin(),e[t].end());
		for(int p:e[t]){
			deg[p]--; if(!deg[p])q.push(p);
			dp[p]=(dp[p]+z)%mod,z=z*mul[p]%mod;
		}
	} for(int i=1;i<=n;i++)cout<<(a[i]*mu+add[i])%mod<<" ";
	return 0;
}

C++(clang++11) 解法, 执行用时: 208ms, 内存消耗: 13564K, 提交时间: 2020-11-08 18:25:00

#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int N=1e5+5;
const int mod=998244353;
int n,m,a[N],b[N],x[N],y[N],ind[N],seq[N],len,mul[N],val[N];
vector<int>vec[N];
queue<int>Q;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%d",&a[i]);
	scanf("%d",&m);
	for(int i=1,t,k,g;i<=m+1;++i){
		if(i<=m)
			scanf("%d",&t);
		else
			t=3;
		mul[i]=1;
		if(t==1)
			scanf("%d%d",&x[i],&y[i]);
		if(t==2)
			scanf("%d",&mul[i]);
		if(t==3){
			scanf("%d",&k);
			while(k--){
				scanf("%d",&g);
				vec[i].push_back(g);
				++ind[g];
			}
		}
	}
	for(int i=1;i<=m+1;++i)
		if(!ind[i])
			Q.push(i);
	while(!Q.empty()){
		int u=Q.front();
		Q.pop();
		seq[++len]=u;
		for(int v:vec[u])
			if(!--ind[v])
				Q.push(v);
	}
	for(int i=m+1;i;--i)
		for(int j:vec[seq[i]])
			mul[seq[i]]=1ll*mul[seq[i]]*mul[j]%mod;
	val[m+1]=1;
	for(int i=1;i<=m+1;++i){
		int u=seq[i];
		if(x[u])
			b[x[u]]=(b[x[u]]+1ll*val[u]*y[u])%mod;
		reverse(vec[u].begin(),vec[u].end());
		for(int v:vec[u]){
			val[v]=(val[v]+val[u])%mod;
			val[u]=1ll*val[u]*mul[v]%mod;
		}
	}
	for(int i=1;i<=n;++i)
		printf("%lld%c",(1ll*a[i]*mul[m+1]+b[i])%mod,i==n?'\n':' ');
	return 0;
}

上一题