题目大意:给你一个图n个点n个边(有向),每个边长度为1,上面有一个数字。给你一个K 对每个点询问距离为k的路径中 所有数的和,以及所有路径中最小的数。n<=100000 K<=10^10
题解:由于k很大,很明显得倍增,于是直接用RMQ就好了。
#include <bits/stdc++.h>
using namespace std;
#define sint long long
const int maxn = 1e5+5;
int f[maxn][42],mn[maxn][42],n,q;
sint sum[maxn][42],k,m;
int main()
{
cin>>n>>k;
for(int i=0;i<n;++i)
cin>>f[i][0];
for(int i=0;i<n;++i)
cin>>mn[i][0],sum[i][0]=mn[i][0];
for(int i=1;i<=40;i++)
{
for(int j=0;j<n;j++)
{
f[j][i]=f[f[j][i-1]][i-1];
mn[j][i]=min(mn[j][i-1],mn[f[j][i-1]][i-1]);
sum[j][i]=sum[j][i-1]+sum[f[j][i-1]][i-1];
}
}
sint s;
int x;
for(int i=0;i<n;i++)
{
x=i;
s=mn[i][0];m=0;
for(int j=0;j<=41;j++)
if( k&(1LL<<j))
{
m+= sum[x][j];
s= min(s,1LL*mn[x][j]);
x= f[x][j];
}
cout<<m<<" "<<s<<endl;
}
return 0;
}