码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3037 lucas

时间:2015-09-09 12:52:53      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

题意 :  给了n课不同的树,要求将 0,1,2,3,4,5,...m个松果,分别放在n棵树上的方案数有多少,

我们这样考虑, 如果将m个相同的松果 放入n棵树中 , 转化一下,我们让每个点至少放1个松果,

将 摆成 一行 n+m 个 ,然后 n+m  中间会有n+m-1个空格 加末尾一个就说明有 n+m个 位置可以插入 东西

假设 第一个被插入的间隔是i表示 1-i之间全部是第一棵树的存放数量,,以此类推,当最后一个插入的间隔没有放在最末尾的时候,表明并没有 那么m个松果可以放的,这样我们求C(n+m,n)就可以了 C(n+m,p)用lucas 计算

技术分享
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <string.h>
 5 using namespace std;
 6 const int maxn =100005;
 7 typedef long long LL;
 8 LL fax[maxn];
 9 void getfax(int p)
10 {
11      fax[0]=1;
12      for(LL i=1; i<=p; i++)
13         {
14              fax[i]=(fax[i-1]*i)%p;
15         }
16 }
17 void gcd(LL a, LL b, LL &d, LL &x, LL &y){
18      if(!b){
19         d=a; x=1; y=0;
20      }else{
21         gcd(b,a%b,d,y,x); y-=x*(a/b);
22      }
23 }
24 LL inv(LL a, LL n)
25 {
26     LL d,x,y;
27     gcd(a,n,d,x,y);
28     return (x+n)%n;
29 }
30 LL lucas(int n, int m, int p)
31 {
32      LL ans=1;
33       while(n&&m)
34         {
35             int a=n%p,b=m%p;
36             if(a<b)return 0;
37             ans=( ( (ans*fax[a])%p  ) * (  inv(fax[b]*fax[a-b] , p)))%p;
38             n/=p;
39             m/=p;
40         }
41     return ans;
42 }
43 int main()
44 {
45     int n,m,p;
46     int cas;
47     scanf("%d",&cas);
48      for(int cc=1; cc<=cas; cc++)
49         {
50             scanf("%d%d%d",&n,&m,&p);
51             getfax(p);
52             printf("%I64d\n",lucas(n+m,n,p));
53         }
54 
55     return 0;
56 }
View Code

 

hdu3037 lucas

标签:

原文地址:http://www.cnblogs.com/Opaser/p/4793983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!