比赛 2025.3.29 评测结果 AAATTTTTTT
题目名称 Analysis of Pathes in Functional Graph 最终得分 30
用户昵称 LikableP 运行时间 11.648 s
代码语言 C++ 内存使用 5.32 MiB
提交时间 2025-03-29 10:09:37
显示代码纯文本
#pragma GCC optimize(2)
#include <cstdio>
#include <cstring>
typedef long long ll;

template <typename T>
T min(T x, T y) {
	return x < y ? x : y;
}

const int MAXN = 1e5 + 10;

int n;
ll k;
int son[MAXN], fa[MAXN];
int w[MAXN];

void Work1() {
	for (int i = 1; i <= n; ++i) {
		int now = i, mini = 0x7fffffff;
		ll sum = 0;
		for (int j = 1; j <= k; ++j) {
			sum += w[now];
			mini = min(mini, w[now]);
			now = son[now];
		}
		printf("%lld %d\n", sum, mini);
	}
}

bool dealt[MAXN], vis[MAXN], vis2[MAXN];
int tolooptimes[MAXN], loopmin[MAXN], loopsize[MAXN], loopstart[MAXN], toloopmin[MAXN];
ll loopsum[MAXN], toloopsum[MAXN];
void CalcLoopLengthAndSum(int root, int tms, ll sum, int k) {
	vis2[root] = 1;
	loopmin[k] = min(loopmin[k], w[root]);
	if (vis2[son[root]]) {
		loopsize[k] = tms + 1;
		loopsum[k] = sum + w[root];
		return ;
	}
	CalcLoopLengthAndSum(son[root], tms + 1, sum + w[root], k);
}
void dfs(int root) {
	dealt[root] = 1;
	vis[root] = 1;
	if (vis[son[root]]) {
		tolooptimes[root] = 1;
		loopmin[root] = w[root];
		toloopsum[root] = w[root];
		loopstart[root] = son[root];
		toloopmin[root] = w[root];
		memset(vis2, 0, sizeof vis2);
		CalcLoopLengthAndSum(root, 0, 0, root);
		return ;
	}
	dfs(son[root]);
	tolooptimes[root] = tolooptimes[son[root]] + 1;
 	loopmin[root] = loopmin[son[root]];
 	toloopmin[root] = min(toloopmin[son[root]], w[root]);
	loopsize[root] = loopsize[son[root]];
	loopsum[root] = loopsum[son[root]];
	toloopsum[root] = toloopsum[son[root]] + w[root];
	loopstart[root] = loopstart[son[root]];
}
void Work2() {
	memset(toloopmin, 0x7f, sizeof toloopmin);
	for (int i = 1; i <= n; ++i) {
		if (dealt[i]) continue;
		memset(vis, 0, sizeof vis);
		dfs(i);
	}

//	for (int i = 1; i <= n; ++i) {
//		printf("#%d fall in loop in %d steps, with mininum weigh %d. Loop size is %d, loop sum is %lld, to loop sum is %lld, loop start at #%d, loop min is %d\n", i, tolooptimes[i], toloopmin[i], loopsize[i], loopsum[i], toloopsum[i], loopstart[i], loopmin[i]);
//	}

	for (int i = 1; i <= n; ++i) {
//		printf("Dealing #%d\n", i);
		ll ans = 0;
		int few = k, now = i, mini = toloopmin[i];
//		printf("set few=%d, now=%d, mini=%d\n", few, now, mini);
		if (few > tolooptimes[i]) {
			ans += toloopsum[i];
			few -= tolooptimes[i];
//			printf("Go loop cost %lld, step last %d\n", ans, few);
			int m = few / loopsize[i];
//			printf("Loop %d times\n", m);
			now = loopstart[i];
			few -= m * loopsize[i];
			ans += m * loopsum[i];
//			printf("ans += %d*%lld, few -= %d*%d\n", m, loopsum[i], m, loopsize[i]);
			if (m) {
				mini = min(mini, loopmin[i]);
//				printf("mini update to %d\n", mini);
			}
		}
//		printf("mini update to %d, few last %d\n", mini, few);
		for (int j = 1; j <= few; ++j) {
//			printf("Steping to %d, weigh %d ", son[now], w[now]);
			ans += w[now];
			mini = min(mini, w[now]);
			now = son[now];
//			printf("mini update to %d\n", mini);
		}
		printf("%lld %d\n", ans, mini);
	}
}

int main() {
	freopen("pathsjump.in", "r", stdin);
	freopen("pathsjump.out", "w", stdout);
	scanf("%d %lld", &n, &k);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &son[i]);
		fa[son[i]] = i;
	}
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &w[i]);
	}
	if (k <= 100) {
		Work1();
	} else {
		Work2();
	}
	return 0;
}