Kyoya and Colored Balls 排列组合+费马小定理求逆元 除法取模

题目链接
题目大意:给球涂颜色,给出了各种颜色需要涂的数量,逐次给每个球涂,要求每种颜色的最后一个球的涂的顺序必须是1,2,3,4,……N,结果较大需要对1 000 000 007取模;
解析:首先最后一个球的颜色必须是N号颜色,那么N号颜色的球还剩data[N]-1个,这data[N]-1个球涂的顺序随意,还有总数(初始设为sum)a=sum-1个位置(最后一个固定),题目给出相同颜色的球相同,这时有组合C(a,data[N]-1)种方式。
对N-1号颜色,最后一个球涂的顺序必须是(注意是最后一个)当前已经涂完N号颜色的序列里的还未放置数据的最后一个,否则不是N-1号颜色,就是比N-1小的颜色,不符合题意。那么对N-1号颜色,还剩data[N-1]-1个球,还有a-1个位置,就有组合C(a,data[N-1]-1)种方式
以此类推
……
……
……
还有一个难点就是取模
因为题目数据多大,而且求组合C中肯定要用到除法,所以就涉及到除法取模公式的运用

逆元: 若,b*b1 % c == 1 则,b1称为b模c的乘法逆元。
在ACM中,许多除法取模都要用到求逆元。 ( a/b ) % c == ( a*b1 ) % c
求一个数逆元模板:

LL power_mod(LL a, LL b, LL mod)///费马小定理求逆元,mod必须为素数,b=mod-2
{
    LL ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
//    inv2=power_mod(a,mod-2,mod);
}

完整代码:

# include <bits/stdc++.h>
using namespace std;
# define MOD 1000000007
# define MAXN 1010
# define LL long long
int data[MAXN];
int N;
LL power_mod(LL a, LL b, LL mod)///费马小定理求逆元
{
    LL ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
//    inv2=power_mod(a,mod-2,mod);
}
int C(int a, int b)
{
    if(a==b||b==0)
        return 1;
    LL ans=1;
    for(int i=a-b+1; i<=a; i++)
    {
        ans=(ans%MOD)*(i%MOD)%MOD;
    }
    LL sum=1;
    for(int i=1;i<=b;i++)
    {
        sum=(sum%MOD)*(i%MOD)%MOD;
    }
    LL c=power_mod(sum,MOD-2,MOD);
    return (ans%MOD)*(c%MOD)%MOD;
}
int main()
{
    while(cin>>N)
    {
        int sum=0;
        for(int i=1; i<=N; i++)
        {
            cin>>data[i];
            sum+=data[i];
        }
        LL ans=1;
        for(int i=N; i>=1; i--)
        {
            LL t=C(sum-1,data[i]-1);
            sum-=data[i];
            ans=(ans%MOD)*(t%MOD)%MOD;
        }
        cout<<ans<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值