zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Python学习札记(十五) 高级特性1 切片
    LeetCode Longest Substring Without Repeating Characters
    Python学习札记(十四) Function4 递归函数 & Hanoi Tower
    single number和变体
    tusen 刷题
    实验室网站
    leetcode 76. Minimum Window Substring
    leetcode 4. Median of Two Sorted Arrays
    leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions 、434. Number of Islands II(lintcode) 并查集 、178. Graph Valid Tree(lintcode)
    刷题注意事项
  • 原文地址:https://www.cnblogs.com/Heey/p/8999566.html
Copyright © 2011-2022 走看看