zoukankan      html  css  js  c++  java
  • Codeforces 771C:Bear and Tree Jumps

    Codeforces 771C:Bear and Tree Jumps

    题目链接:http://codeforces.com/problemset/problem/771/C

    题目大意:给出一个$n(2 leqslant n leqslant 200,000)$个结点的无根树及整数$k(1 leqslant k leqslant 5)$,求$sum f(s,t),(s<t)$,其中$f(s,t)=lceil frac{dis(s,t)}{k} ceil$.

    树形DP

    设$dis(u,v)$为$u$到$v$的简单路径长度,则$f(u,v)=lceil frac{dis(u,v)}{k} ceil=frac{dis(u,v)+L(u,v)}{k}$,于是问题就转化为求$sum dis(u,v)$和$sum L(u,v)$.

    $sum dis(u,v)$可以很容易求得:任取一结点为根,每条边的贡献为$num[x] imes (n-num[x])$,其中$x$为该边的子结点,$num[x]$为$x$的子树的结点个数.

    关键在于求$sum L(u,v)$.定义$dp[i][j]$为从$i$的子树出发到达$i$结点,简单路径长度模$k$为$j$的个数.设$u$为$v$的父节点,根据$dp[u][i]$和$dp[v][j]$,可以求得包含$u$,$v$结点的路径长模为$(i+j+1)\%k$的路径数为$dp[u][i] imes dp[v][j]$条,从而可以求出相应的$sum L(x,y)$.转移方程为$dp[u][(i+1)\%k]=dp[u][(i+1)\%k]+dp[v][i]$.

    于是$ans=sum frac{dis(u,v)+L(u,v)}{k}$,复杂度为$O(nk^2)$

    代码如下:

     1 #include <iostream>
     2 #include <vector>
     3 #include <cstring>
     4 #define N 200005
     5 using namespace std;
     6 typedef long long ll;
     7 int n,k;
     8 ll ans,dp[N][6],sum[N];
     9 vector<int>e[N];
    10 ll dfs(int u,int pre){
    11     dp[u][0]=sum[u]=1;
    12     for(int t=0;t<(int)e[u].size();++t){
    13         int v=e[u][t];
    14         if(v!=pre){
    15             sum[u]+=dfs(v,u);
    16             for(int i=0;i<k;++i)
    17             for(int j=0;j<k;++j){
    18                 ll need=(k-(i+j+1)%k)%k;//when k-(i+j+1)%k==kor0 it need not add;
    19                 ans+=need*dp[u][i]*dp[v][j];
    20             }
    21             for(int i=0;i<k;++i)
    22                 dp[u][(i+1)%k]+=dp[v][i];
    23         }
    24     }
    25     ans+=sum[u]*(n-sum[u]);
    26     return sum[u];
    27 }
    28 int main(void){
    29     std::ios::sync_with_stdio(false);
    30     cin>>n>>k;
    31     for(int i=1;i<n;++i){
    32         int u,v;
    33         cin>>u>>v;
    34         e[u].push_back(v);
    35         e[v].push_back(u);
    36     }
    37     dfs(1,-1);
    38     cout<<ans/k;
    39 }
  • 相关阅读:
    201671010145 20162017 《Java程序设计》java的继承中什么叫方法覆盖,是如何实现的?
    201671010145 20162017《Java程序设计》Java接口的功能
    Java与C语言的区别
    201671010145 201620173《Java程序设计》Java中类与对象的区别
    Java 加密算法
    Java 基础
    Java 新建线程时使用线程池处理
    sublime text 3安装
    C语言的基本数据类型
    有点跑题的随笔
  • 原文地址:https://www.cnblogs.com/barrier/p/6583088.html
Copyright © 2011-2022 走看看