环上倍增,直接倍增

/*
只需要直到下一个走到点是谁,那就可以进行倍增的处理
而不需要去是否成环的问题
直到他的下一个点就可以了
环上倍增也是一个道理,可以直接走下去
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define br cout<<"----------------------------\n";
const int M=1e5+5;
int n,k;
//向下走是谁,最小值,权值和
int f1[M][36],f2[M][36],f3[M][36];
void init_st() {
for(int j=1;j<=35;j++)
for(int i=1;i<=n;i++) { //这里需要延长一点
f1[i][j]=f1[f1[i][j-1]][j-1];
f2[i][j]=min(f2[i][j-1],f2[f1[i][j-1]][j-1]);
f3[i][j]=f3[i][j-1]+f3[f1[i][j-1]][j-1];
// cout<<f1[i][j]<<' '<<f2[i][j]<<' '<<f3[i][j]<<'\n';
}
}
int query1(int st,int k) {
int ans=0;
for(int i=35;i>=0;i--)
if((1ll<<i)<=k)k-=(1ll<<i),ans+=f3[st][i],st=f1[st][i];
return ans;
}
int query2(int st,int k) {
int mn=1e9;
for(int i=35;i>=0;i--)
if((1ll<<i)<=k)k-=(1ll<<i),mn=min(mn,f2[st][i]),st=f1[st][i];
return mn;
}
void solve() {
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>f1[i][0],f1[i][0]++;
for(int i=1,x;i<=n;i++)cin>>x,f2[i][0]=f3[i][0]=x;
init_st();
for(int i=1;i<=n;i++)
cout<<query1(i,k)<<' '<<query2(i,k)<<'\n';
}
signed main() {
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
solve();
return 0;
}
posted @   basicecho  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示