zoukankan      html  css  js  c++  java
  • 【LGP5437】【XR-2】约定

    题目

    显然每一条边出现在生成树中的方案数是相等的

    根据矩阵树定理,(n)个节点的完全图生成树个数是(n^{n-2})种,完全图共有(frac{n(n-1)}{2})条边,一棵生成树共(n-1)条边

    于是对于任意一条边,在所有生成树中的总出现次数是

    [frac{n^{n-2}(n-1)}{frac{n(n-1)}{2}}=2n^{n-3} ]

    于是每一条边前面多了一个系数,可以理解为每一条边出现的概率

    [frac{2n^{n-3}}{n^{n-2}}=frac{2}{n} ]

    这个东西乘上边权和(sum_{i=1}^nsum_{j=i+1}^n(i+j)^k)

    显然(i,j)都从(1)开始更好求一些,于是求一下(sum_{i=1}^nsum_{j=1}^n(i+j)^k),减去(sum_{i=1}^n(2i)^k=2^ksum_{i=1}^ni^k),再除以(2)就是总边权和了

    不要在傻乎乎的二项式定理拆里面的东西了,我们直接枚举(i+j)的值,显然这玩意长得跟个矩阵是的,每一条对角线上的值都是一样的,还有一些对称的美好性质,于是瞎推一下就有

    [sum_{i=1}^nsum_{j=1}^n(i+j)^k=sum_{i=1}^{n+1}i^{k+1}-sum_{i=1}^{n+1}i^k+(2n+1)sum_{i=n+2}^{2n}i^k-sum_{i=n+2}^{2n}i^{k+1} ]

    大力拉格朗日插值就好了

    代码

    #include<bits/stdc++.h>
    #define re register
    const int maxn=1e7+5;
    const int mod=998244353;
    inline int ksm(int a,int b) {
        int S=1;
        for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) S=1ll*S*a%mod;
        return S;
    }
    int f[maxn],p[maxn>>2],pre[maxn][2],a[maxn],b[maxn],fac[maxn],ifac[maxn];
    int n,k,ans1,ans2,ans3,ans4;
    inline int qm(int a) {return a<0?a+mod:a;}
    inline int calc(int x,int o) {
        int N=(o==1?k+2:k+1);
        a[0]=b[0]=x;b[N+1]=1;
        for(re int i=1;i<=N;i++) a[i]=1ll*a[i-1]*(b[i]=qm(x-i))%mod;
        for(re int i=N-1;i>=0;--i) b[i]=1ll*b[i]*b[i+1]%mod;
        int tot=0;
        for(re int i=1;i<=N;i++) {
    	int now=1ll*ifac[i]*ifac[N-i]%mod;
    	if((N-i)&1) now=mod-now;
    	now=1ll*now*a[i-1]%mod*b[i+1]%mod;
    	tot=(tot+1ll*now*pre[i][o]%mod)%mod;
        }
        return tot;
    }
    int main() {
        scanf("%d%d",&n,&k);fac[0]=ifac[0]=1;pre[1][0]=pre[1][1]=1;
        for(re int i=2;i<=k+2;i++) {
    	if(!f[i]) p[++p[0]]=i,pre[i][0]=ksm(i,k),pre[i][1]=ksm(i,k+1);
    	for(re int j=1;j<=p[0]&&p[j]*i<=k+2;++j) {
    	    pre[p[j]*i][0]=1ll*pre[p[j]][0]*pre[i][0]%mod;
    	    pre[p[j]*i][1]=1ll*pre[p[j]][1]*pre[i][1]%mod;
    	    f[p[j]*i]=1;if(i%p[j]==0) break;
    	}
        }
        for(re int i=1;i<=k+2;i++) fac[i]=1ll*fac[i-1]*i%mod;
        ifac[k+2]=ksm(fac[k+2],mod-2);
        for(re int i=k+1;i;--i) ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
        for(re int i=1;i<=k+1;++i) pre[i][0]=(pre[i-1][0]+pre[i][0])%mod;
        for(re int i=1;i<=k+2;++i) pre[i][1]=(pre[i-1][1]+pre[i][1])%mod;
        ans1=calc(n+1,1);ans2=calc(2*n,1)-ans1;
        ans3=calc(n+1,0),ans4=calc(2*n,0)-ans3;
        ans2=(ans2+mod)%mod,ans4=(ans4+mod)%mod;
        ans4=1ll*ans4*(2*n+1)%mod;
        int ans=(ans1+ans4)%mod-(ans2+ans3)%mod;
        ans=(ans+mod)%mod;
        ans=(ans-1ll*ksm(2,k)*calc(n,0)%mod+mod)%mod;
        printf("%d
    ",1ll*ans*ksm(n,mod-2)%mod);
        return 0;
    }
    
    
  • 相关阅读:
    POJ 1300 Open Door
    POJ 2230 Watchcow
    codevs 1028 花店橱窗布置
    codevs 1021 玛丽卡
    codevs 1519 过路费
    codevs 3287 货车运输
    codevs 3305 水果姐逛水果街二
    codevs 1036 商务旅行
    codevs 4605 LCA
    POJ 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/asuldb/p/11286980.html
Copyright © 2011-2022 走看看