zoukankan      html  css  js  c++  java
  • [2016北京集训试题8]连在一起的幻想乡[dp+无向图计数]

    Description

    Solution

    本博客参考yww大佬的博客,为了加深理解我就自己再写一遍啦。

    以下的“无向图”均无重边无自环。

    定义f0[n]为n个点构成的无向图个数,f1[n]为n个点构成的无向图的总边数,f2[n]为所有(n个点构成的无向图的边数的平方)之和。

    g0[n]为n个点构成的连通无向图个数,g1[n]为n个点构成的连通无向图的总边数,g2[n]为所有(n个点构成的连通无向图的边数的平方)之和。

    设$m[i]=i*(i-1)/2$

    每条边可以选或不选,所以$f0[i]=2^{m[i]}$

    由于每条边会在$2^{m[i]-1}$个图中被选,$f1[i]=m[i]*2^{m[i]-1}$

    求f2的公式要运用一个套路:枚举与1号点连通的边数j,则$f2[i]=sum_{j=0}^{i-1}*sum _{k=0}^{m[i]-j}*((j+k)^{2}$*(i-1个点的无向图边数为k的个数))

    即$f2[i]=sum_{j=0}^{n-1}$*[(i-1个点无向图个数*j)的平方+2*j*(i-1个点无向图总边数)+所有(i-1个点构成的无向图的边数的平方)之和)

    故$f2[i]=sum_{j=0}^{n-1}*inom{i-1}{j}*(f2[i-1]+2*j*f1[i-1]+j^{2}*f0[i-1])$。

    我们枚举点1所在连通块点数,$g0[i]=f0[i]-sum _{j=1}^{i-1}*inom{i-1}{j-1}g0[j]*f0[i-j]$
    $g1[i]=f1[i]-sum _{j=1}^{i-1}*inom{i-1}{j-1}(g0[j]*f1[i-j]+g1[j]*f0[i-j])$

    $g2[i]=f2[i]-sum _{j=1}^{i-1}*inom{i-1}{j-1}(g0[j]*f2[i-j]+2*g1[j]*f1[i-j]+g2[j]*f0[i-j])$

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    int n,mod;
    ll C[2010][2010],m[2010],g0[2010],g1[2010],g2[2010],f0[2010],f1[2010],f2[2010];
    ll ksm(ll x,ll k)
    {ll re=1;if (k==-1) return 0;while (k){if (k&1)re=re*x%mod;k>>=1;x=x*x%mod;}return re;}
    int main()
    {
        scanf("%d%d",&n,&mod);
        for (int i=0;i<=n;i++) C[i][0]=1;
        for (int i=1;i<=n;i++) for (int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        for (int i=1;i<=n;i++) m[i]=i*(i-1)/2;
        for (int i=1;i<=n;i++) f0[i]=ksm(2,m[i]),f1[i]=m[i]*ksm(2,m[i]-1)%mod;
        for (int i=1;i<=n;i++) 
            for (int j=0;j<i;j++) 
            f2[i]=(f2[i]+(f2[i-1]+2*j*f1[i-1]+j*j*f0[i-1])%mod*C[i-1][j]%mod+mod)%mod;
        for (int i=1;i<=n;i++) 
        {
            g0[i]=f0[i];g1[i]=f1[i];g2[i]=f2[i];
            for (int j=1;j<i;j++)
            {
                g0[i]=(g0[i]-C[i-1][j-1]*g0[j]%mod*f0[i-j]%mod+mod)%mod;
                g1[i]=(g1[i]-C[i-1][j-1]*((g0[j]*f1[i-j]+g1[j]*f0[i-j])%mod)%mod+mod)%mod;
                g2[i]=(g2[i]-C[i-1][j-1]*((g0[j]*f2[i-j]+2*g1[j]*f1[i-j]+g2[j]*f0[i-j])%mod)%mod+mod)%mod;
            }
        }
        printf("%lld",g2[n]);
    }
  • 相关阅读:
    Appium+python自动化20-查看iOS上app元素属性【转载】
    Appium+python自动化19-iOS模拟器(iOS Simulator)安装自家APP【转载】
    Appium+python自动化18-brew、carthage和appium-doctor【转载】
    Appium+python自动化17-启动iOS模拟器APP源码案例【转载】
    Appium+python自动化16-appium1.6在mac上环境搭建启动ios模拟器上Safari浏览器【转载】
    Appium+python自动化15-在Mac上环境搭建【转载】
    Centos-清屏命令-clear
    Centos-切换用户身份-su
    Centos-修改密码-passwd
    Centos-显示或修改系统时间与日期-date
  • 原文地址:https://www.cnblogs.com/coco-night/p/9657962.html
Copyright © 2011-2022 走看看