【拓扑排序】P7077 [CSP-S2020] 函数调用

题意

n n n个元素,进行一些函数的操作。
功能可分为三类:

  1. 单点加;
  2. 全局乘;
  3. 依次执行若干次函数调用,保证不会出现递归(即不会直接或间接地调用本身)。

思路

考虑给这些函数的调用关系建图,得到一个DAG。

若无操作1,则用拓扑排序计算出每个函数调用后给全局乘上的值。

考虑算上操作1,那么对于一个加法后的乘法,会给加法的贡献也乘上一个权值,那么可以倒着进行一次拓扑排序,算出每个加法被乘上之后的贡献。

代码

#include 
#include 
#include 
#define int long long

const int mod = 998244353;

std::vector<int> G1[100001], G2[100001];
int n, m;
int a[100001], mul[100001], cnt[100001], pos[100001], add[100001], deg[100001];

void topsort1() {
	std::queue<int> q;
	for (int i = 0; i <= m; i++) {
		deg[i] = G2[i].size();
		if (!deg[i])
			q.push(i);
	}
	while (q.size()) {
		int x = q.front();
		q.pop();
		for (int i = 0; i != G1[x].size(); i++) {
			int y = G1[x][i];
			(mul[y] *= mul[x]) %= mod;
			deg[y]--;
			if (!deg[y])
				q.push(y);
		}
	}
}

void topsort2() {
	std::queue<int> q;
	for (int i = 0; i <= m; i++) {
		deg[i] = G1[i].size();
		if (!deg[i])
			q.push(i);
	}
	while (q.size()) {
		int x = q.front();
		q.pop();
		int now = 1;
		for (int i = G2[x].size() - 1; i >= 0; i--) {
			int y = G2[x][i];
			(cnt[y] += now * cnt[x] % mod) %= mod;//具体地,通过计算每个函数操作次数来算贡献
			(now *= mul[y]) %= mod;
			deg[y]--;
			if (!deg[y])
				q.push(y);
		}
	}
}

signed main() {
	scanf("%lld", &n);
	for (int i = 1; i <= n; i++)
		scanf("%lld", &a[i]);
	scanf("%lld", &m);
	mul[0] = 1;
	for (int i = 1; i <= m; i++) {
		mul[i] = 1;
		int typ;
		scanf("%lld", &typ);
		if (typ == 1) {
			scanf("%lld %lld", &pos[i], &add[i]);
		} else if (typ == 2) {
			scanf("%lld", &mul[i]);
		} else {
			int len;
			scanf("%lld", &len);
			for (int j = 1, x; j <= len; j++) {
				scanf("%lld", &x);
				G1[x].push_back(i);
				G2[i].push_back(x);
			}
		}
	}
	int Q;
	scanf("%lld", &Q);
	for (int i = 1, x; i <= Q; i++) {
		scanf("%lld", &x);
		G1[x].push_back(0);
		G2[0].push_back(x);
	}
	cnt[0] = 1;
	topsort1();
	topsort2();
	for (int i = 1; i <= n; i++)
		(a[i] *= mul[0]) %= mod;
	for (int i = 1; i <= m; i++)
		(a[pos[i]] += cnt[i] * add[i] % mod) %= mod;
	for (int i = 1; i <= n; i++)
		printf("%lld ", a[i]);
}

你可能感兴趣的:(windows,OI,csp2021)