CodeForces 702E Analysis of Pathes in Functional Graph(倍增)

讲道理这个应该是类似矩阵的东西,但是太大了也不现实,相对应的,倍增可以解决的就是类似这样的单路径移动?思想上类似状压dp,本质。。好像也是dp


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <stack>
#include <queue>
#include <string.h>
#include <string>
#include <iomanip>
#include <cstring>
#include <vector>
#include <functional>
#include <cmath>
#include <sstream>
#include <set>

using namespace std;
#define PI acos(-1.0)
typedef long long ll;
//typedef unsigned long long ull;
#define sp system("pause")

const int N = 100000 + 10;
const int M = 35;
const int mod = 1e9 + 7;
const int inf = 1e9 + 7;
int f[N][M];   //记录第N个点第2^M次是在哪个点上
ll sum[N][M]; //记录第N个点经过2^M次的之和
int mn[N][M]; //几率第N个点经过2^M次的路径中的最小值

int main()
{
	int n;
	ll k;
	cin >> n >> k;
	for (int i = 0; i < n; i++)scanf("%d", &f[i][0]); //当前位置
	for (int i = 0; i < n; i++){
		scanf("%d", &sum[i][0]); mn[i][0] = sum[i][0];
	}
	for (int j = 1; j < M; j++)
	{
		for (int i = 0; i < n; i++)
		{
			f[i][j] = f[f[i][j - 1]][j - 1];    // 第i个点2^j-1次之后的点  经过2^j-1次  就是第i点经过2^j次
			sum[i][j] = sum[f[i][j - 1]][j - 1] + sum[i][j - 1]; //前面后后一段, 后面前一段
			mn[i][j] = min(mn[i][j - 1], mn[f[i][j - 1]][j - 1]); //同上
		}
	}
	ll ans;
	for (int i = 0; i < n; i++)
	{
		int v = i, minn = inf;
		ans = 0;
		for (int j = M - 1; j >= 0; j--)
		{
			ll xx = 1; xx <<= j;
			if (k&xx)      //枚举当前次数
			{
				ans += sum[v][j];
				minn = min(minn, mn[v][j]);
				v = f[v][j];   //将当前点转移到f[v][j]
			}
		}
		printf("%I64d %d\n", ans, minn);
	}
	//sp;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值