zoukankan      html  css  js  c++  java
  • BZOJ 5093: [Lydsy1711月赛]图的价值

    第二类斯特林数模版题

    需要一些组合数的小$ trick$

    upd:这里更新了本题巧妙的$ O(k)$做法,虽然常数很大就是了


    传送门:here

    题意:求所有$ n$个节点的无重边自环图的价值和,定义一张图的价值为每个点度数的$ k$次方和,点有标号


    $ Solution$

    显然每个节点的贡献是独立的

    枚举每个节点的度数,和这个点不联通的边可连可不连

    $ ans=n*2^{frac{(n-1)(n-2)}{2}} sumlimits_{i=0}^{n-1}i^kC_{n-1}^i$

    我们实际要求解的东西就是$ f(n,m)=sumlimits_{i=0}^ni^mC_n^i$

    把$i^m$用斯特林数展开得
    $f(n,m)=sumlimits_{i=0}^nsumlimits_{j=0}^mC_i^jS(m,j)j!C_n^i$

    把$j$移动到前面得
    $f(n,m)=sumlimits_{j=0}^mS(m,j)j!sumlimits_{i=0}^nC_i^jC_n^i$
    考虑后面这个$sumlimits_{i=0}^nC_i^jC_n^i$是什么
    本质相当于在$n$个物品中选出集合$A$,再在集合$A$中选取$j$个物品
    也就是在$n$个物品中选取$j$个物品,其他$n-j$个物品可在集合$A$中也可不在
    因此$sumlimits_{i=0}^nC_i^jC_n^i=C_n^j2^{n-j}$
    $f(n,m)=sumlimits_{j=0}^mS(m,j)j!C_n^j2^{n-j}$
    $NTT$筛出斯特林数直接计算即可
    复杂度$O(k log k)$


    $my code$

    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define p 998244353
    #define file(x)freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    #define rt register int
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x = 0; char zf = 1; char ch = getchar();
        while (ch != '-' && !isdigit(ch)) ch = getchar();
        if (ch == '-') zf = -1, ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x * zf;
    }
    void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
    void writeln(const ll y){write(y);putchar('
    ');}
    int i,j,k,m,n,x,y,z,cnt;
    int a[1000010],b[1000010],R[1000010],lim;
    ll ksm(ll x,ll y){
        if(!y)return 1;ll ew=1;
        while(y>1){
            if(y&1)y--,ew=x*ew%p;
            y>>=1,x=x*x%p;
        }return x*ew%p;
    }
    int inv[200010],S[200010];
    struct poly{
        int n,m,lim;
        void init(int k){
            //a[i]=(-1)^i / i!    b[i] = i^k/i!
            n=k;
            a[0]=1;b[0]=0;
            for(rt i=1;i<=k;i++){
                a[i]=-1ll*a[i-1]*inv[i]%p;
                b[i]=ksm(i,k)*a[i]%p;
                if(i&1)b[i]=-b[i];
            }
            lim=1;while(lim<=n+n)lim<<=1;
            for(rt i=1;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1?(lim>>1):0);
        }
        void NTT(int *A,int fla){
            for(rt i=0;i<lim;i++)if(i<R[i])swap(A[i],A[R[i]]);
            for(rt i=1;i<lim;i<<=1){
                ll w=ksm(3,p/2/i);
                for(rt j=0;j<lim;j+=i<<1){
                    ll K=1;
                    for(rt k=0;k<i;k++,K=K*w%p){
                        ll x=A[j+k],y=K*A[i+j+k];
                        A[j+k]=(x+y)%p;A[i+j+k]=(x-y)%p;
                    }
                }
            }
            if(fla==-1){
                reverse(A+1,A+lim);
                for(rt i=0;i<=n;i++)S[i]=1ll*A[i]*ksm(lim,p-2)%p;
            }
            
        }
        void main(int k){
            init(k);
            NTT(a,1);NTT(b,1);
            for(rt i=0;i<lim;i++)a[i]=1ll*a[i]*b[i]%p;
            NTT(a,-1);
        }
    }NTT;
    int main(){
        n=read()-1;k=read();
        inv[0]=inv[1]=1;
        for(rt i=2;i<=k+1;i++)inv[i]=1ll*inv[p%i]*(p-p/i)%p;
    
        NTT.main(k);
        ll jc=1,C=1,ans=0,sum=ksm(2,n-j);
        for(rt j=0;j<=k;j++){
            (ans+=S[j]*jc%p*C%p*sum)%=p;
            jc=jc*(j+1)%p;C=C*(n-j)%p*inv[j+1]%p;
            sum=sum*inv[2]%p;
        }
        cout<<(ans*(n+1)%p*ksm(2,(ll)n*(n-1)/2)%p+p)%p;
        return 0;
    }
  • 相关阅读:
    Nginx internal 指令限制访问图片资源文件
    Laravel 5 中文文档 CHM 版
    Educational Codeforces Round 89 (Rated for Div. 2)
    Markdown写的第一篇文章,猜猜里边有什么东西吧!
    Git暂存流程
    Java BIO、NIO与AIO的介绍(学习过程)
    如何在Mac中安装telnet
    使用IDEA编译java程序时,出现的编译错误: error:java:错误:不支持发行版本5
    Java中请优先使用try-with-resources而非try-finally
    Redis入门学习(学习过程记录)
  • 原文地址:https://www.cnblogs.com/DreamlessDreams/p/9882335.html
Copyright © 2011-2022 走看看