Codeforces 711C 树DP 解题报告

来源:互联网 发布:vue.js nexttick用法 编辑:程序博客网 时间:2024/06/07 21:12

C. 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 n vertices, numbered 1 through n.
Limak recently learned how to jump. He can jump from a vertex to any vertex within distance at most k.
For a pair of vertices (s, t) we define f(s, t) as the minimum number of jumps Limak needs to get from s to t. Your task is to find the sum of f(s, t) over all pairs of vertices (s, t) such that s < t.

Input

The first line of the input contains two integers n and k (2 ≤ n ≤ 200 000, 1 ≤ k ≤ 5) — the number of vertices in the tree and the maximum allowed jump distance respectively.
The next n - 1 lines describe edges in the tree. The i-th of those lines contains two integers ai and bi (1 ≤ ai, bi ≤ n) — the indices on vertices connected with i-th edge.
It’s guaranteed that the given edges form a tree.

Output

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

Examples

input
6 2
1 2
1 3
2 4
2 5
4 6
output
20
input
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
output
114
input
3 5
2 1
3 1
output
3

【解题报告】

代码如下:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define LL long long#define N 200010int cnt=-1,head[N];struct Edge{int to,nxt;}e[N<<1];int n,k;LL dp[N][10],size[N],ans;void adde(int u,int v){    e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;    e[++cnt].to=u;e[cnt].nxt=head[v];head[v]=cnt;}void dfs(int u,int fa,int dep){    size[u]=dp[u][dep%k]=1;     for(int i=head[u];~i;i=e[i].nxt)    {        int v=e[i].to;        if(v==fa) continue;        dfs(v,u,dep+1);        for(int a=0;a<k;a++)          for(int b=0;b<k;b++)        {            int dis=((a+b)%k-(dep*2)%k+k)%k;              ans+=((k-dis)%k)*dp[u][a]*dp[v][b];          }        for(int a=0;a<k;a++) dp[u][a]+=dp[v][a];            ans+=size[v]*(n-size[v]);          size[u]+=size[v];      }}int main(){    memset(head,-1,sizeof(head));    scanf("%d%d",&n,&k);    for(int i=1;i<n;++i)    {        int u,v;scanf("%d%d",&u,&v);        adde(u,v);    }    dfs(1,1,0);    printf("%I64d\n",ans/k);    return 0;}
原创粉丝点击