zoukankan      html  css  js  c++  java
  • Perm 排列计数

    排列组合这部分确实很水,但关键是想到树,堆。

    i与2×i,2×i+1有关,符合树上节点编号的特点,加上大小限制就是堆的性质了。

    这个堆中存的是节点编号所以大小固定,每个节点的size[i]固定往里边填数(排列组合部分);

    设f[i]是以i为根的组合方案数,

    f[i]=f[i*2]*f[i*2+1]*C(size[i]-1,size[2*i]),在符合比i大的数里随机选size[2*i]个分给左树,剩下的是右数。

    n,m很大用lucas定理。

    C(n,m)%p=C(n%p,m%p)*C(n/p,m/p);

    递归:lucas(n,m)( =C(n,m)%p )=C(n%p,m%p)*lucas(n/p,m/p)%p;

    阶乘可以打表。虽然P可能到1e9,但n%p,一定小于n,所以打到n就完事了。

    逆元部分可打表也可快速幂:

    根据费马小定理。

    p为质,x^p-1同余1(mod p);所以x*x^p-2同余1;x的逆元就是x^p-2;

    ll C(int n,int m)
    {
        if(m>n) return 0;
        return fac[n]*qpow(fac[m]*fac[n-m]%p,p-2)%p;
    }

    %p也可以在快速幂里写但不能忽略,因为a*a%p这可能会炸...WA36原因。

    1不是质数不考虑。

    总结:树编号的特点灵活用,知识间的结合,观察数列,数,编号的特点疯狂联想。

              lucas定理。

              mod p要考虑清楚是否需要是否可能炸。

    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define ll long long
    const int maxn=2e6+5;
    int n,p,size[maxn];
    ll f[maxn],fac[maxn];
    void init()
    {
        fac[0]=1;
        int turn=min(n,p);
        for(int i=1;i<=turn;i++)
            fac[i]=fac[i-1]*i%p;
    }
    ll qpow(ll a,int b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=ans*a%p;
            b>>=1;
            a=a*a%p;
        }
        return ans;
    }
    ll C(int n,int m)
    {
        if(m>n) return 0;
        return fac[n]*qpow(fac[m]*fac[n-m]%p,p-2)%p;
    }
    ll lucas(int n,int m)
    {
       if(!m) return 1;
       return C(n%p,m%p)*lucas(n/p,m/p)%p;
    }
    ll F(int x)
    {
        if(x>n) return 1;
        f[x]=( F(2*x)*F(2*x+1) )%p *lucas(size[x]-1,size[2*x]) %p;
        return f[x];
    }
    int Size(int x)
    {
        if(x>n) return 0;
        size[x]=Size(2*x)+Size(2*x+1)+1;
        return size[x];
    }
    int main()
    {
        scanf("%d%d",&n,&p);
        if(p==1)
        {
            printf("0");
            return 0;
        }
        init();
        size[1]=Size(1);
        f[1]=F(1);
        printf("%lld",f[1]);
    }
    View Code
  • 相关阅读:
    XAML学习笔记之Layout(五)——ViewBox
    XAML学习笔记——Layout(三)
    XAML学习笔记——Layout(二)
    XAML学习笔记——Layout(一)
    从0开始搭建SQL Server 2012 AlwaysOn 第三篇(安装数据,配置AlwaysOn)
    从0开始搭建SQL Server 2012 AlwaysOn 第二篇(配置故障转移集群)
    从0开始搭建SQL Server 2012 AlwaysOn 第一篇(AD域与DNS)
    Sql Server 2012 事务复制遇到的问题及解决方式
    Sql Server 2008R2升级 Sql Server 2012 问题
    第一次ACM
  • 原文地址:https://www.cnblogs.com/three-D/p/11126738.html
Copyright © 2011-2022 走看看