【CF771C】Bear and Tree Jumps

题目

题目描述
A tree is an undirected connected graph without cycles. The distance between two vertices is the number of edges in a simple path between them.

Limak is a little polar bear. He lives in a tree that consists of nn vertices, numbered 11 through nn .

Limak recently learned how to jump. He can jump from a vertex to any vertex within distance at most kk .

For a pair of vertices (s,t)(s,t) we define f(s,t)f(s,t) as the minimum number of jumps Limak needs to get from ss to tt . Your task is to find the sum of f(s,t)f(s,t) over all pairs of vertices (s,t)(s,t) such that s<t .

输入格式
The first line of the input contains two integers nn and kk ( 2<=n<=2000002<=n<=200000 , 1<=k<=51<=k<=5 ) — the number of vertices in the tree and the maximum allowed jump distance respectively.

The next n-1n−1 lines describe edges in the tree. The ii -th of those lines contains two integers a_{i}a
i

and b_{i}b
i

( 1<=a_{i},b_{i}<=n1<=a
i

,b
i

<=n ) — the indices on vertices connected with ii -th edge.

It’s guaranteed that the given edges form a tree.

输出格式
Print one integer, denoting the sum of f(s,t)f(s,t) over all pairs of vertices (s,t)(s,t) such that s<t .

题意翻译
有一颗n个结点且有n-1条边的无根树

一只熊可以从当前节点可以跳到任何与当前节点距离不超过k的节点

定义f(u,v)f(u,v)为熊从u点到v点所需的最少跳跃次数,那么,对于树上的所有点对(u,v)(u,v),f(u,v)f(u,v)的总和是多少。

注意:

(u,v)(u,v)和(v,u)(v,u)视作同一个点对,只计算一次答案

输入输出样例
输入 #1复制
6 2
1 2
1 3
2 4
2 5
4 6
输出 #1复制
20
输入 #2复制
13 3
1 2
3 2
4 2
5 2
3 6
10 6
6 7
6 13
5 8
5 9
9 11
11 12
输出 #2复制
114
输入 #3复制
3 5
2 1
3 1
输出 #3复制
3
说明/提示
In the first sample, the given tree has 66 vertices and it’s displayed on the drawing below. Limak can jump to any vertex within distance at most 22 . For example, from the vertex 55 he can jump to any of vertices: 11 , 22 and 44 (well, he can also jump to the vertex 55 itself).

There are pairs of vertices (s,t)(s,t) such that s<t . For 55 of those pairs Limak would need two jumps: (1,6),(3,4),(3,5),(3,6),(5,6)(1,6),(3,4),(3,5),(3,6),(5,6) . For other 1010 pairs one jump is enough. So, the answer is 5·2+10·1=205⋅2+10⋅1=20 .

In the third sample, Limak can jump between every two vertices directly. There are 33 pairs of vertices (s<t) , so the answer is 3·1=33⋅1=3 .

思路

考虑树形dp
设f[u][i]为u的子树中与u的距离为i的点的答案
对于i>0,可以由儿子转移到父亲
对于i=0,也就说点u的答案,就要分类讨论

  1. 对于距离<k的点,贡献为1
  2. 对于距离>k的点,可以先跳k格,然后由那一个点转移

转移方程长这样:
在这里插入图片描述

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+77;
int n,k,sz[N];
vector<int> g[N];
ll f[N][5];
void dfs1(int u,int p)
{
	sz[u]=1;
	for(int v:g[u])
		if(v!=p)
		{
			dfs1(v,u);
			sz[u]+=sz[v],f[u][0]+=f[v][k-1]+sz[v];
			for(int i=1; i<k; i++) f[u][i]+=f[v][i-1];
		}
}
void dfs2(int u,int p)
{
	ll t[5]={0};
	if(p)
	{
		t[0]=f[p][0]-f[u][k-1]-sz[u];
		for(int i=1; i<k; i++) t[i]=f[p][i]-f[u][i-1];
	}
	f[u][0]+=t[k-1]+n-sz[u];
	for(int i=1; i<k; i++) f[u][i]+=t[i-1];
	for(int v:g[u]) if(v!=p) dfs2(v,u);
}
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1; i<n; i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].push_back(v); g[v].push_back(u);
	}
	dfs1(1,0); dfs2(1,0);
	ll ans=0;
	for(int i=1; i<=n; i++) ans+=f[i][0];
	printf("%lld",ans/2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
股价的跳空是指股票价格在连续交易日之间出现大幅度的价格差异。在Python中,可以使用一些库和函数来计算股价的跳空。 引用\[2\]中提到了使用tl.jump.calc_jump_line()函数来获取跳空能量大于阈值的缺口。这个函数可以帮助我们筛选出跳空能量较大的缺口。例如,可以设置一个跳空能量筛选阈值,如2.8,然后使用该函数来计算跳空缺口。 引用\[3\]中提到了tl.jump.calc_jump_line_weight()函数,与上面使用的calc_jump_line()函数不同之处在于它根据时间权重重新计算了跳空能量。这意味着根据时间线性加权的结果,较早的跳空缺口的能量可能会被降低,而较近的跳空缺口的能量仍然保持不变。 因此,如果你想在Python中计算股价的跳空,可以使用这些函数来筛选和计算跳空缺口的能量。 #### 引用[.reference_title] - *1* [lstm预测股票_股票相关性与lstm预测误差](https://blog.csdn.net/weixin_26750511/article/details/109070595)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [第13节 量化技术分析应用](https://blog.csdn.net/weixin_31901801/article/details/114431033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值