*题解:CF702E Analysis of Pathes in Functional Graph

题目链接

解析

静态查询区间最大值与和可以用 ST 表来解决。而放在基环树上也是一样的道理,设 \(nxt_{i,j}\) 表示从 \(j\)\(2 ^ i\) 条边到达的点,类似地设计出表示最大值与和的状态,倍增即可。

时间复杂度 \(O(n \log k)\)

代码

/*
*/
#include <bits/stdc++.h>
#define eps 0.0000000001
using namespace std;
typedef long long ll;
typedef unsigned ui;
typedef pair<ll, ll> pii;
const int N = 30 + 5, M = 100000 + 5, P = 450, mod = 1e9 + 7, mod2 = 1e9 + 7, b1 = 131;
int f[M],nxt[N][M],mn[N][M];
ll w[M],sum[N][M];
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
// 	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stderr);
	ll n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>f[i];
		f[i]++;
		nxt[0][i] = f[i];
	}
	for(int i=1;i<=n;i++){
		cin>>w[i];		
		mn[0][i] = sum[0][i] = w[i];
	}
	for(int i=1;i<N;i++){
		for(int j=1;j<=n;j++){
			nxt[i][j] = nxt[i - 1][nxt[i - 1][j]];
			mn[i][j] = min(mn[i - 1][j],mn[i - 1][nxt[i - 1][j]]);
			sum[i][j] = sum[i - 1][j] + sum[i - 1][nxt[i - 1][j]];
		}
	}
	for(int i=1;i<=n;i++){
		ll now = k;
		int pos = i;
		int resm = 2e9;
		ll ress = 0;
		for(int i=N - 1;i>=0;i--){
			if(now >= (1ll << i)){
				resm = min(resm,mn[i][pos]);
				ress += sum[i][pos];
				pos = nxt[i][pos];
				now -= (1ll << i);
			}
		}
		cout<<ress<<" "<<resm<<'\n';
	}
    return 0;
}

posted @ 2026-07-19 13:04  yutar  阅读(4)  评论(0)    收藏  举报