hdu3037 lucas
2015-09-09 10:54
211 查看
题意 : 给了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 计算
View Code
我们这样考虑, 如果将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 计算
#include <iostream> #include <algorithm> #include <cstdio> #include <string.h> using namespace std; const int maxn =100005; typedef long long LL; LL fax[maxn]; void getfax(int p) { fax[0]=1; for(LL i=1; i<=p; i++) { fax[i]=(fax[i-1]*i)%p; } } void gcd(LL a, LL b, LL &d, LL &x, LL &y){ if(!b){ d=a; x=1; y=0; }else{ gcd(b,a%b,d,y,x); y-=x*(a/b); } } LL inv(LL a, LL n) { LL d,x,y; gcd(a,n,d,x,y); return (x+n)%n; } LL lucas(int n, int m, int p) { LL ans=1; while(n&&m) { int a=n%p,b=m%p; if(a<b)return 0; ans=( ( (ans*fax[a])%p ) * ( inv(fax[b]*fax[a-b] , p)))%p; n/=p; m/=p; } return ans; } int main() { int n,m,p; int cas; scanf("%d",&cas); for(int cc=1; cc<=cas; cc++) { scanf("%d%d%d",&n,&m,&p); getfax(p); printf("%I64d\n",lucas(n+m,n,p)); } return 0; }
View Code
相关文章推荐
- JavaScript中实现Map的示例代码
- Win 8系统中为IE浏览器添加Flash插件的方法
- ViewController生命周期详解
- java类加载器的秘密
- Android Studio SDK 更新方法
- iOS - 正则表达式判断邮箱、身份证..是否正确
- 使用curl命令操作elasticsearch
- RFM模型及R语言实现
- Swift UIImageView 构造方法
- VxWorks操作系统shell命令与调试方法总结
- Expected a type 的错误
- 第二次作业
- 文件的特殊权限:SUID SGID SBIT
- 如何使用Zipalign工具优化Android APK应用
- Html 简单语法总结
- JBPM4.4——与SSH的集成运用
- PHP register_shutdown_function函数详解
- STM32时钟配置
- Swift 2.0学习笔记(Day 10)——运算符是“ +、-、*、/ ”吗?
- Linux多线程服务器-门禁打卡系统