zoukankan      html  css  js  c++  java
  • 题解 hdu6810 Imperative Meeting

    题解 hdu6810 Imperative Meeting

    题目链接

    题目描述

    给定一棵 (n) 个点的树,每条边长度为 (1) ,定义点集 (S) 的函数 (f(S))

    [f(S)=min_{u=1}^n(sum_{vin S}mbox{dis}(u,v)) ]

    (说人话就是 (S) 到它们的重心的距离和)

    给定 (m) ,求 (sum_{|S|=m}f(S))

    题目分析

    做法一

    由于某个点集 (S) 的重心可能不唯一,所以我们先以 (1) 为根建立一棵有根树,然后钦定点集 (S) 选的重心要是深度最小的点,这样重心就是唯一的。

    设点 (u) 的子树大小为 (mbox{size}(u)) ,某个点集 (S)(u) 内的点的数量为 (s(u)),那么 (u)(S) 的重心当且仅当 (2s(u)>mland forall vin mbox{son}_u,2s(v)le m) 。考虑到 (u) 的所有儿子中最多只能有一个儿子 (v)(2s(v)>m) ,所以设 (f(u)) 表示满足 (2s(u)>m)(S) 的方案数,那么 (u) 作为 (S) 重心的方案数就是 (f(u)-sum_{vin mbox{son}_u}f(v))

    如何求 (f(u)) ?不难发现 (f(u)) 只和 (mbox{size}(u)) 有关,设 (g(x)=sum_{2i>m}{xchoose i}{n-xchoose m-i}) ,那么 (f(u)=g(mbox{size}(u)))(g(x)) 的算法和在做法二中的类似。

    找到了重心,就可以开始求距离了,对于 (u) 的每一个儿子子树,其中每个点出现在 (S) 中的方案数都是相同的,设 (g_0(x)=sum_{2i>m}{x-1choose i-1}{n-xchoose m-i})(f_0(u)=g_0(mbox{size}(u))) ,那么对于 (u) 的儿子 (v_0) 子树中的任意一个点出现在 (S) 中的方案数是 (f_0(u)-sum_{vin mbox{son}_u,v e v_0}f(v)-f_0(v_0)) ,那么 (v_0) 子树对于以 (u) 为重心时的点集的贡献就是 (v_0) 子树中所有点到 (u) 的距离再乘以出现的方案数,于是就可以求答案了。对于 (u) 的父亲节点所在的子树用类似的方法即可。

    感觉这种做法特别复杂,还有一个比较简单的方法。

    做法二

    做法一是按点来算贡献的,考虑换一种方法,按边来算贡献。

    对于一条边,如果它连接着的两边的点的数量分别是 (a)(b) ,那么它的贡献就是 (min(a,b)) ,以 (1) 为根建树,设此时每个点的子树大小为 (mbox{size}())(f(x)=sum_{i=0}^mmin(i,m-i){xchoose i}{n-xchoose m-i}) ,那么答案就是 (sum_{i=2}^nf(mbox{size}(i)))

    如何求 (f(x)) ?可以把 (f(x)) 分成两半计算,即 (sum_{i=0}^ti{xchoose i}{n-xchoose m-i}+sum_{i=t+1}^m(m-i){xchoose i}{n-x choose m-i}) ,设前半部分为 (g(x)) ,则:

    [g(x)=sum_{i=0}^ti{xchoose i}{n-xchoose m-i}\ =sum_{i=0}^tx{x-1choose i-1}{n-xchoose m-i}\ frac{g(x)}{x}=sum_{i=0}^t{x-1choose i-1}{n-xchoose m-i} ]

    (s(x)=sum_{i=0}^C{xchoose i}{A-xchoose B-i}) ,考虑递推 (s(x))

    [s(x)=sum_{i=0}^C{xchoose i}{A-xchoose B-i}\ =sum_{i=0}^C[{x-1choose i-1}+{x-1choose i}][{A-x+1choose B-i}-{A-xchoose B-i-1}]\ =sum_{i=0}^C{x-1choose i}{A-x+1choose B-i}+sum_{i=0}^C{x-1choose i-1}{A-xchoose B-i}-sum_{i=0}^C{x-1choose i}{A-xchoose B-i-1}\ =s(x-1)+sum_{i=-1}^{C-1}{x-1choose i}{A-xchoose B-i-1}-sum_{i=0}^C{x-1choose i}{A-xchoose B-i-1}\ =s(x-1)+{x-1choose -1}{A-xchoose B}-{x-1choose C}{A-xchoose B-C-1} ]

    于是就可以算 (f(x)) 了。

    参考代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ch() getchar()
    #define pc(x) putchar(x)
    using namespace std;
    template<typename T>void read(T&x){
    	static char c;static int f;
    	for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
    	for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
    }
    template<typename T>void write(T x){
    	static char q[65];int cnt=0;
    	if(x<0)pc('-'),x=-x;
    	q[++cnt]=x%10,x/=10;
    	while(x)
    		q[++cnt]=x%10,x/=10;
    	while(cnt)pc(q[cnt--]+'0');
    }
    const int maxn=1000005,mod=1000000007;
    int mo(const int x){
    	return x>=mod?x-mod:x;
    }
    int iac[maxn],fac[maxn];
    int binom(int n,int m){
    	return n<0||m<0||m>n?0:1ll*iac[m]*iac[n-m]%mod*fac[n]%mod;
    }
    int f[maxn];
    int fa[maxn],sz[maxn];
    int main(){
    	fac[0]=fac[1]=iac[0]=iac[1]=1;
    	for(int i=2;i<maxn;++i)
    		iac[i]=1ll*(mod-mod/i)*iac[mod%i]%mod;
    	for(int i=2;i<maxn;++i)
    		iac[i]=1ll*iac[i-1]*iac[i]%mod,fac[i]=1ll*fac[i-1]*i%mod;
    	int T;read(T);
    	while(T--){
    		int n,m;read(n),read(m);
    		int mx=(m-1)/2;
    		f[1]=(mx==0?0:binom(n-1,m-1));
    		for(int i=2;i<n;++i)
    			f[i]=mo(mod-1ll*binom(i-2,mx-1)*binom(n-i,m-mx-1)%mod+f[i-1]);
    		for(int i=1;i<n;++i)
    			f[i]=1ll*f[i]*i%mod;
    		for(int i=1;i<=n-i;++i){
    			f[i]=f[n-i]=mo(f[i]+f[n-i]);
    			if(!(m&1))f[i]=f[n-i]=mo(f[i]+1ll*binom(i,mx+1)*binom(n-i,mx+1)%mod*(mx+1)%mod);
    		}
    		for(int i=2;i<=n;++i){
    			sz[i]=1;read(fa[i]);
    		}
    		sz[1]=1;int ans=0;
    		for(int i=n;i>=2;--i){
    			sz[fa[i]]+=sz[i];
    			ans=mo(ans+f[sz[i]]);
    		}
    		write(ans),pc('
    ');
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    【spring 事务注解配置】事务回滚
    myisam 和 innodb 对比
    mysql replace into用法详细说明
    [nginx] 配置
    【lucene】中文分词
    Lucene 4.9 document的简单应用
    Spring事务配置的五种方式
    Open-Drain与Push-Pull
    HDMI中的AVmute是什么功能
    在Keil uv5里面添加STC元器件库,不影响其他元件
  • 原文地址:https://www.cnblogs.com/lsq147/p/14299928.html
Copyright © 2011-2022 走看看