XidianOJ 1057 卡尔的技能

题目描述

dota中的英雄卡尔的技能说明如下,他拥有3种不同的元素(冰,雷,火),每次他需要释放技能的时候,他要先选择3次元素来决定释放技能的类型(比如,他可以选择火+火+火或冰+雷+火等等),生成技能的类型由选择的元素中各个元素的比例决定,比如选择冰+冰+雷和选择冰+雷+冰会生成同样的技能,这种机制下,卡尔一共拥有10个技能。
冰+冰+冰:急速冷却
冰+冰+雷:幽灵漫步
冰+冰+火:寒冰之墙
雷+雷+冰:强袭飓风
雷+雷+雷:电磁脉冲
雷+雷+火:灵动迅捷
火+火+火:炎阳冲击
火+火+雷:混沌陨石
冰+雷+火:超震声波
火+火+冰:熔炉精灵
现在,为了加强卡尔,使可供选择的元素达到n个(3<=n<=10^12),选择的次数达到m次(3<=m<=10^12),那么卡尔头疼了,他到底能拥有多少种不同的技能呢?

 

输入

多组数据
每组数据包含两个整数,n和m

 

输出

对于每组数据输出一行,即对应的结果(答案对10007取模)

--正文

仔细一看,这题换个形式就是:

   m个相同的球,放到n个盒子里,允许有空盒的方案数

所以就是C(n+m-1,m)

因为n,m比较大所以需要使用Lucas

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

typedef long long LL;
LL Fast_Mod(LL a,LL b,LL MOD){
    LL res = 1,base = a;
    while (b){
        if (b&1) res = (res*base) % MOD;
        base = (base*base) % MOD;
        b = b >> 1;
    }
    return res;
}
LL fac[10009],n,m;
void Getfac(LL p){
    fac[0] = 1;
    int i;
    for (i=1;i<=p;i++){
        fac[i] = (fac[i-1]*i) % p;
    }
}
LL Lucas(LL n,LL m,LL p){
    LL res = 1;
    while (n && m){
        LL a = n % p,b = m % p;
        if (a < b) return 0;
        res = (res*fac[a]*Fast_Mod(fac[b]*fac[a-b]%p,p-2,p)) % p;
        n = n / p; m = m / p;
    } 
    return res;
}

int main(){
    Getfac(10007);
    while (scanf("%lld %lld",&n,&m) != EOF){
        printf("%lld\n",Lucas(n+m-1,m,10007));
    }
}

 

转载于:https://www.cnblogs.com/ToTOrz/p/6169837.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值