zoukankan      html  css  js  c++  java
  • CF1097G Vladislav and a Great Legend

    先对式子进行转化:

    [largeegin{aligned} &sum_S(f(S))^k \ =&sum_Ssum_{i=0}^kegin{Bmatrix} k \i end{Bmatrix}inom{f(S)}{i}i! \ =&sum_{i=0}^kegin{Bmatrix} k \i end{Bmatrix}i!sum_Sinom{f(S)}{i} \ end{aligned} ]

    第一项直接枚举即可,第二项的组合意义为从点集为 (S) 的连通块中选出 (i) 条边的方案数。

    考虑树形 (DP),设 (f_{i,j}) 为经过 (i) 的连通块中选 (j) 条边的方案数。分类讨论来合并子树即可:①不选该子树。②选该子树,且连通块内只有该子树。③选该子树,且连通块内不只有该子树。

    #include<bits/stdc++.h>
    #define maxn 200010
    #define maxm 210
    #define p 1000000007
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,m;
    int siz[maxn];
    ll val=1,ans;
    ll sum[maxm],f[maxn][maxm],g[maxm],S[maxm][maxm];
    struct edge
    {
        int to,nxt;
    }e[maxn];
    int head[maxn],edge_cnt;
    void add(int from,int to)
    {
        e[++edge_cnt]={to,head[from]},head[from]=edge_cnt;
    }
    void dfs(int x,int fa)
    {
        siz[x]=f[x][0]=1;
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to;
            if(y==fa) continue;
            dfs(y,x);
            for(int j=0;j<=min(siz[x],m);++j)
            {
                for(int k=0;k<=min(siz[y],m);++k)
                {
                    if(j+k>m) break;
                    ll v=f[x][j]*f[y][k]%p;
                    g[j+k]=(g[j+k]+v)%p,sum[j+k]=(sum[j+k]+v)%p;
                    g[j+k+1]=(g[j+k+1]+v)%p,sum[j+k+1]=(sum[j+k+1]+v)%p;
                }
            }
            for(int j=0;j<=m;++j)
            {
                f[x][j]=(f[x][j]+g[j]+f[y][j])%p,g[j]=0;
                if(j) f[x][j]=(f[x][j]+f[y][j-1])%p;
            }
            siz[x]+=siz[y];
        }
    }
    void init()
    {
        S[0][0]=1;
        for(int i=1;i<=m;++i)
            for(int j=1;j<=i;++j)
                S[i][j]=(S[i-1][j]*j%p+S[i-1][j-1])%p;
    }
    int main()
    {
        read(n),read(m),init();
        for(int i=1;i<n;++i)
        {
            int x,y;
            read(x),read(y);
            add(x,y),add(y,x);
        }
        dfs(1,0);
        for(int i=1;i<=m;++i)
            val=val*i%p,ans=(ans+S[m][i]*val%p*sum[i]%p)%p;
        printf("%lld",ans);
        return 0;
    }
    
  • 相关阅读:
    PCI Express体系结构导读(3)- PCIE
    PCI Express体系结构导读(2)
    npm添加代理和取消代理
    流媒体压力测试rtmp&hls(含推流和拉流)
    流媒体跳坑: 03-视频会议:使用LiveRTC来做视频直播
    流媒体跳坑: 02-视频会议:Webrtc服务器
    正交调制解调(MATLAB)
    mp4文件断电保存-(关于:MP4视频文件损坏的一点想法)
    流媒体跳坑: 01-Mp4 文件解析
    centos 守护 node 进程
  • 原文地址:https://www.cnblogs.com/lhm-/p/13888011.html
Copyright © 2011-2022 走看看