xdoj1057(卡尔的技能)

8 篇文章 0 订阅

1057: 卡尔的技能

时间限制: 1 Sec   内存限制: 128 MB
提交: 120   解决: 51
[ 提交][ 状态][ 讨论版]

题目描述

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

输入

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

输出

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

样例输入

3 3
3 4

样例输出

10
15
思路:把几次选择看成相同的小球,每个属性看成不同的盒子,小球入盒,盒可为空。用Lucas求解。用白书上的板子死活不对,无奈,从网上找了一套板子。
上代码:
#include<bits/stdc++.h> //Lucas定理的板子 
using namespace std;
 typedef long long  ll;
ll f[10008];  
const int p=10007;  
void init()  
{  
    f[0]=1;  
    for(int i=1;i<=10007;i++)  
    f[i]=(f[i-1]*i)%p;  
}  
ll pow(ll a,int b)  
{  
    ll ans=1;  
    while(b)  
    {  
        if(b&1)  
        ans=ans*a%p;  
        a=a*a%p;  
        b>>=1;  
    }  
    return ans;  
}  
ll C(ll a,int b)  
{  
    if(b>a)  
    return 0;  
    return f[a]*(pow(f[b]*f[a-b],p-2))%p;  
}  
ll lucas(ll n,ll m)  
{  
    if(m==0)  
    return 1;  
    else return (C(n%p,m%p)*lucas(n/p,m/p))%p;  
} 
int main()
{
     ll n,m;
     while(scanf("%lld%lld",&n,&m)!=EOF)
     {
		 init();
		  ll res=lucas(n+m-1,m);
		 printf("%lld\n",res);
     }
     return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值