zoukankan      html  css  js  c++  java
  • [BZOJ 2142]礼物(扩展Lucas定理)

    Description

    一年一度的圣诞节快要来到了。每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物。不同的人物在小E心目中的重要性不同,在小E心中分量越重的 人,收到的礼物会越多。小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi。请你帮忙计算出送礼物的方案数(两个方案被认为是 不同的,当且仅当存在某个人在这两种方案中收到的礼物不同)。由于方案数可能会很大,你只需要输出模P后的结果。

    Solution

    扩展Lucas的板子题

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    typedef long long LL;
    LL Mod,n,m,w;
    LL read()
    {
        LL x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    LL pow(LL a,LL n,LL p)
    {
        LL res=1;
        while(n)
        {
            if(n&1)res=(res*a)%p;
            a=(a*a)%p,n>>=1;
        }
        return res;
    }
    void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
    {
        if(!b)d=a,x=1,y=0;
        else exgcd(b,a%b,d,y,x),y-=x*(a/b);
    }
    LL inv(LL a,LL p)
    {
        LL d,x,y;exgcd(a,p,d,x,y);
        return (x+p)%p==0?p:(x+p)%p;
    }
    LL fac(LL n,LL p,LL pk)
    {
        if(n==0)return 1;
        LL res=1;
        for(LL i=2;i<=pk;i++)
            if(i%p)res=(res*i)%pk;
        res=pow(res,n/pk,pk);
        for(LL i=2;i<=n%pk;i++)
            if(i%p)res=(res*i)%pk;
        return (res*fac(n/p,p,pk))%pk;
    }
    LL C(LL n,LL m,LL p,LL pk)
    {
        if(n<m)return 0;
        LL a=fac(n,p,pk),b=fac(m,p,pk),c=fac(n-m,p,pk);
        LL k=0;
        for(LL i=n;i;i/=p)k+=i/p;
        for(LL i=m;i;i/=p)k-=i/p;
        for(LL i=n-m;i;i/=p)k-=i/p;
        LL res=(((a*inv(b,pk))%pk)*inv(c,pk))%pk*pow(p,k,pk)%pk;
        return res*(Mod/pk)%Mod*inv(Mod/pk,pk)%Mod;
    }
    LL Lucas(LL n,LL m)
    {
        LL res=0,P=Mod;
        for(LL i=2;i<=P;i++)
            if(P%i==0)
            {
                LL pk=1;
                while(P%i==0)P/=i,pk*=i;
                res=(res+C(n,m,i,pk))%Mod;
            }
        return res;
    }
    int main()
    {
        Mod=read(),n=read(),m=read();
        LL ans=1;
        for(int i=1;i<=m;i++)
        {
            w=read();
            if(n<w){printf("Impossible");return 0;}
            ans=(ans*Lucas(n,w))%Mod;
            n-=w;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    AX 2012 Security Framework
    The new concept 'Model' in AX 2012
    How to debug the SSRS report in AX 2012
    Using The 'Report Data Provider' As The Data Source For AX 2012 SSRS Report
    Deploy SSRS Report In AX 2012
    AX 2012 SSRS Report Data Source Type
    《Taurus Database: How to be Fast, Available, and Frugal in the Cloud》阅读笔记
    图分析理论 大纲小结
    一文快速了解Posix IO 缓冲
    #转载备忘# Linux程序调试工具
  • 原文地址:https://www.cnblogs.com/Zars19/p/6993918.html
Copyright © 2011-2022 走看看