排列组合 快速幂

链接:https://ac.nowcoder.com/acm/contest/699/F
来源:牛客网

题目描述

        从前有个小哥哥Bill非常喜欢编程,但是让他更加心动的是班上那位小姐姐,为了取得小姐姐的欢心,Bill每天刷acm题,只想着找一个机会大发雄威。机会来了!有一天,老师为了提高同学们学习数学的积极性,做了一个小游戏:六位同学分为一组,每个同学心中想着自己最喜欢的数字a,b,c,e,f,g,对于(ax+by+cz)的k次方展开式中,(x^e)(y^f)(z^g)的系数是多少,当游戏开始时参与游戏的人需要在1秒内报出结果是多少。Bill一时兴奋忘了拿电脑,你能在下面帮助他赢得女神的欢心么?

输入描述:

输入包含7个整数,分别为a ,b ,c, k ,e ,f, g每两个整数之间用一个空格隔开。(0≤k≤1,000,  0≤e,f,g≤k,且e+f+g=k ,0 ≤a,b,c ≤1000000)

输出描述:

输出一行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007取模后的结果。
示例1

输入

复制
3 2 1 4 1 2 1

输出

复制
144
示例2

输入

复制
1 5 3 3 1 2 0

输出

复制
75
#include<cstdio>
using namespace std;
#define mod 10007
#define ll long long

ll pows(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1){
            ans=(ans*a)%mod;
        }
        a=(a*a)%mod;
        b=b>>1;
    }
    return ans;
}

ll C1(ll a,ll b){//取模排列组合 
    ll i,ret=1;
    for(i=2;i<=a;i++){
        ret=(ret*i)%mod;
    }
    for(i=2;i<=b;i++){
        ret=(ret*pows(i,mod-2))%mod;
    }
    for(i=2;i<=a-b;i++){
        ret=(ret*pows(i,mod-2))%mod;
    }
    return ret;
}

ll C2(ll a,ll b){//不取模排列组合 
    ll ans=1;
    for(ll i=1;i<=b;i++){
        ans=(ans*(a-b+1)/i);
    }
    return ans;
} 

int main(){
    int a,b,c,k,e,f,g;
    ll sum=1;
    scanf("%d%d%d%d%d%d%d",&a,&b,&c,&k,&e,&f,&g);
    sum=(sum*pows(c,g)%mod)%mod;
    sum=(sum*pows(a,e)%mod)%mod;
    sum=(sum*pows(b,f)%mod)%mod;
    sum=(sum*C1(k,g)%mod)%mod;
    sum=(sum*C1(k-g,e)%mod)%mod;
    printf("%lld
",sum);
    return 0;
}
原文地址:https://www.cnblogs.com/qqshiacm/p/10746942.html