zoukankan      html  css  js  c++  java
  • [BZOJ2111][ZJOI2010]Perm 排列计数

    这显然是一个二叉堆,然而我一开始sha bi了,没想到树的形态是唯一的QwQ。因为是1到n的一个排列,所以数两两不同。用f[i]表示以二叉堆中编号为i的节点为根的子树的方案数,然后考虑如何求f,设lc,rc分别为i的左右子节点,则f[i]=f[lc]*f[rc]*C(size[i]-1,size[lc]),size就是子树大小。为什么*C(size[i]-1,size[lc])呢,这是左子树有哪些数的方案数,而i一定是最小的,所以i一定是根。组合数取模用Lucas就好了~

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #include<vector>
    typedef long long LL;
    using namespace std;
    const int N=2e6+10;
    LL n,p,f[N],fac[N],siz[N];
    LL read() {LL d=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=(d<<3)+(d<<1)+c-48,c=getchar(); return d*f;}
    void judge(){freopen(".in","r",stdin); freopen(".out","w",stdout);}
    LL quickmi(LL a,LL b,LL p)
    {
        LL res=1;
        while (b)
        {
            if (b&1) res=res*a%p;
            a=a*a%p; b>>=1;
        }
        return res;
    }
    LL C(LL n,LL m,LL p)
    {
        if (n<m) return 0;
        if (n==m) return 1;
        return fac[n]*quickmi(fac[m]*fac[n-m]%p,p-2,p)%p;
    }
    LL lucas(LL n,LL m,LL p)
    {
        LL res=1;
        while (n&&m&&res)
        {
            res=res*C(n%p,m%p,p)%p;
            n/=p; m/=p;
        }
        return res;
    }
    int main()
    {
        //judge();
        n=read(); p=read();
        fac[1]=1;
        for (int i=2;i<=n;i++) fac[i]=fac[i-1]*i%p;
        for (int i=n;i>=1;i--)
        {
            int lc=i<<1,rc=lc|1;
            siz[i]=siz[lc]+siz[rc]+1;
            if (lc>n) f[lc]=1; if (rc>n) f[rc]=1;
            f[i]=f[lc]*f[rc]%p*lucas(siz[i]-1,siz[lc],p)%p;
        }
        printf("%lld",f[1]);
        return 0;
    }
    View Code
  • 相关阅读:
    周日讲课材料下载
    基础图论练习题
    邻接表存图的小trick(存多个图)
    0/1分数规划
    四道期望题
    基础线性代数大记(二)三道高消题
    基础线性代数大记 (一)前言与行列式的定义
    概率期望小记
    基础线性代数小记
    给二维数组排版
  • 原文地址:https://www.cnblogs.com/lujiaju6555/p/6788969.html
Copyright © 2011-2022 走看看