• BZOJ#2142. 礼物



    题目:

    Description

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


    分析:

    裸的Lucas

    ans=∏(C(n,w) (n=n-Σwi)

    式子的意思就是每次进来一个人,答案就要乘上C(n,w),n是现在还剩下的礼物个数

    因为前面的人已经选走了Σwi个礼物,只剩下n-Σwi个礼物可以选

    #include<bits/stdc++.h>
    using namespace std;
    
    long long read()
    {
        long long x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    long long mod,n,m,w;
    
    long long qpow(long long a,long long b,long long p)
    {
        long long ans=1LL;
        while(a>0)
        {
            if(a&1) ans=(ans*b)%p;
            b=(b*b)%p;
            a>>=1;
        }
        return ans;
    }
    
    void exgcd(long long a,long long b,long long &x,long long &y)
    {
        if(b==0) {x=1;y=0;return ;}
        exgcd(b,a%b,x,y);
        long long temp=x;
        x=y;
        y=temp-a/b*y;
    }
    
    long long inv(long long a,long long p)
    {
        long long x,y;
        exgcd(a,p,x,y);
        x=(x%p+p)%p;
        if(!x) x=p;
        return x;    
    }
    
    long long Mul(long long n,long long pi,long long pk)
    {
        if(!n) return 1LL;
        long long ans=1LL;
        if(n/pk) 
        {
            for(long long i=2;i<=pk;i++) if(i%pi) ans=(ans*i)%pk;
            ans=qpow(n/pk,ans,pk);
        }
        for(long long i=2;i<=n%pk;i++) if(i%pi) ans=(ans*i)%pk;
        return (ans*Mul(n/pi,pi,pk))%pk;
        
    }
    
    long long C(long long n,long long m,long long pi,long long pk)
    {
        if(n<m) return 0;
        long long a=Mul(n,pi,pk),b=Mul(m,pi,pk),c=Mul(n-m,pi,pk);
        long long k=0;
        for(long long i=n;i;i/=pi) k+=i/pi;
        for(long long i=m;i;i/=pi) k-=i/pi;
        for(long long i=n-m;i;i/=pi) k-=i/pi;
        long long ans=((a*inv(b,pk)%pk*inv(c,pk)%pk)%pk*qpow(k,pi,pk))%pk;
        return ans*(mod/pk)%mod*inv(mod/pk,pk)%mod;
    }
    
    long long Lucas(long long n,long long m)
    {
        long long ans=0;
        long long x=mod;
        for(long long i=2;i<=x;i++)
        {
            long long pk=1;
            if(x%i==0) 
            {
                while(x%i==0) pk*=i,x/=i;
                ans=(ans+C(n,m,i,pk))%mod;
            }
        }
        return ans;
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        
        mod=read();n=read();m=read();
        long long 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;
    }
    View Code

  • 相关阅读:
    c++ 11 thread 初试
    java UDP聊天与文件传输
    iOS 基础类解析
    Hadoop HA高可用集群搭建(2.7.2)
    object-c 不定參数的遍历和原理
    9.4 返回更新后的行
    java面向接口编程
    Node.js开发入门—套接字(socket)编程
    shell脚本输出带颜色字体
    shell--read命令
  • 原文地址:https://www.cnblogs.com/Heey/p/8999566.html
Copyright © 2020-2023  润新知