zoukankan      html  css  js  c++  java
  • 【LOJ6044】「雅礼集训 2017 Day8」共(prufer序列)

    点此看题面

    • 求有多少棵(n)个点的、以(1)号点为根的有根树,满足恰好有(k)个点深度为奇数((1)号点深度为(1))。
    • (nle5 imes10^5),当(n>10^3)时模数为(998244353)

    (prufer)序列的经典应用

    首先有一个组合数(C_{n-1}^{k-1}),表示从除(1)之外的点中选出剩余的深度为奇数的点的方案数。

    由于只可能奇数度数和偶数度数的点之间存在边,且每对奇数度数和偶数度数的点之间都可能存在边,因此我们现在有一张两边点数分别是(k)(n-k)的完全二分图。

    然后就可以借鉴【BZOJ4766】文艺计算姬的结论,这样一张图中的生成树个数就是(k^{n-k-1}cdot(n-k)^{k-1})

    代码:(O(n^2)/O(n))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define BN 1000
    using namespace std;
    int n,k,X;I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
    I int Fac(RI x) {RI t=1;W(x) t=1LL*t*(x--)%X;return t;}//暴力算阶乘
    int c[BN+5][BN+5];I int C(CI x,CI y)//组合数
    {
    	if(x<=BN) {for(RI i=c[0][0]=1;i<=x;++i) for(RI j=c[i][0]=1;j<=i;++j) c[i][j]=(c[i-1][j-1]+c[i-1][j])%X;return c[x][y];}//暴力求组合数
    	else return 1LL*Fac(x)*QP(1LL*Fac(y)*Fac(x-y)%X,X-2)%X;//x>BN时必定有逆元,套用组合数计算公式
    }
    int main()
    {
    	return scanf("%d%d%d",&n,&k,&X),printf("%d
    ",1LL*C(n-1,k-1)*QP(k,n-k-1)%X*QP(n-k,k-1)%X),0;//选点方案×建树方案
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/LOJ6044.html
Copyright © 2011-2022 走看看