• Codeforces554C:Kyoya and Colored Balls(组合数学+费马小定理)


    Kyoya Ootori has a bag with n colored balls that are colored with k different colors. The colors are labeled from 1 to k. Balls of the same color are indistinguishable. He draws balls from the bag one by one until the bag is empty. He noticed that he drew the last ball of color ibefore drawing the last ball of color i + 1 for all i from 1 to k - 1. Now he wonders how many different ways this can happen.

    Input

    The first line of input will have one integer k (1 ≤ k ≤ 1000) the number of colors.

    Then, k lines will follow. The i-th line will contain ci, the number of balls of the i-th color (1 ≤ ci ≤ 1000).

    The total number of balls doesn't exceed 1000.

    Output

    A single integer, the number of ways that Kyoya can draw the balls from the bag as described in the statement, modulo 1 000 000 007.

    Sample test(s)
    input
    3
    2
    2
    1
    
    output
    3
    
    input
    4
    1
    2
    3
    4
    
    output
    1680
    
    Note

    In the first sample, we have 2 balls of color 1, 2 balls of color 2, and 1 ball of color 3. The three ways for Kyoya are:

    1 2 1 2 3
    1 1 2 2 3
    2 1 1 2 3
    
    
    题意:
    有k种颜色。每种颜色相应a[i]个球,球的总数不超过1000
    要求第i种颜色的最后一个球,其后面接着的必须是第i+1种颜色的球
    问一共同拥有多少种排法
    
    
    思路:
    首先我们easy想到我们必需要确定每种颜色最后一个球的放法
    全部对于最后一种颜色,如果这样的颜色有b个球,而总球数为a
    那么必定有一个球是放在最后一个位置的,那么剩下的球就是z=C(b-1,a-1)种方法
    那么对于倒数另外一种球,如果有x个,此时总球数位y=a-b
    那么之前已经有z种方法了。而对于每一种放法。此时倒数另外一种颜色拿出一个作为最后一个球的话,它对于每种放法必定仅仅有一个固定方法,位置是最后一个没有放球的位置。这样既保证放法符合要求,而剩下的球就有C(x-1,y-1)种放法
    然后相乘得到最后一种颜色与最后另外一种颜色的方法,以此类推。。
    能够使用费马小定理来优化组合数计算
    
    
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define LL long long
    const LL mod =  1000000007;
    LL n;
    LL a[1005];
    LL fac[1000005];
    
    
    LL ppow(LL a,LL b)
    {
        LL c=1;
        while(b)
        {
            if(b&1) c=c*a%mod;
            b>>=1;
            a=a*a%mod;
        }
        return c;
    }
    
    
    LL work(LL m,LL i)
    {
        return ((fac[m]%mod)*(ppow((fac[i]*fac[m-i])%mod,mod-2)%mod))%mod;
    }
    
    int main()
    {
        LL i,j,k;
        fac[0] = 1;
        for(i = 1; i<1000005; i++)
            fac[i]=(fac[i-1]*i)%mod;
        LL ans = 1,sum = 0;
        scanf("%I64d",&n);
        for(i = 1; i<=n; i++)
        {
            scanf("%I64d",&a[i]);
            sum+=a[i];
        }
        for(i = n; i>=1; i--)
        {
            ans*=work(sum-1,a[i]-1);
            ans%=mod;
            sum-=a[i];
        }
        printf("%I64d
    ",ans);
    
        return 0;
    }
    


  • 相关阅读:
    PHP后门新玩法:一款猥琐的PHP后门分析
    中国菜刀批量导出数据
    渗透测试:反弹与转发小结
    怎样用Java自制优秀的图片验证码?这样!
    6条 Tips 为你照亮 GitHub 寻宝之路
    如何搭建一个“不可告人的”私人专属网盘?教程拿去
    6个炫酷又好用的 Python 工具,个个都很奔放呀
    20个Java练手项目,献给嗜学如狂的人
    如何自己动手写一个搜索引擎?我是一份害羞的教程🙈
    GitHub上个最有意思的项目合集(技术清单系列)
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6745042.html
Copyright © 2020-2023  润新知