题意:问用不超过 m 颗种子放到 n 棵树中,有多少种方法。

析:题意可以转化为 x1 + x2 + .. + xn = m,有多少种解,然后运用组合的知识就能得到答案就是 C(n+m, m)。

然后就求这个值,直接求肯定不好求,所以我们可以运用Lucas定理,来分解这个组合数,也就是Lucas(n,m,p)=C(n%p,m%p)* Lucas(n/p,m/p,p)。

然后再根据费马小定理就能做了。

代码如下:

第一种:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <unordered_map>
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 10005;
const LL mod = 10000000000007;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int hr[]= {-2, -2, -1, -1, 1, 1, 2, 2};
const int hc[]= {-1, 1, -2, 2, -2, 2, -1, 1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
LL exgcd(LL a,LL b,LL &x,LL &y){LL d = a;if(b!=0){d=exgcd(b,a%b,y,x);y-=(a/b)*x;}else{x=1;y=0;}return d;}
LL mod_inverse(LL a,LL m){LL x,y;exgcd(a,m,x,y);return (m+x%m)%m; }
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
LL fact[100005]; LL mod_fact(LL n, LL p, LL &e){
e = 0;
if(!n) return 1;
LL res = mod_fact(n / p, p, e);
e += n / p;
if(n / p % 2 != 0) return res * (p - fact[n%p]) % p;
return res * fact[n%p] % p;
} LL mod_comb(LL n, LL k, LL p){
if(n < 0 || k < 0 || n < k) return 0;
LL e1, e2, e3;
LL a1 = mod_fact(n, p, e1);
LL a2 = mod_fact(k, p, e2);
LL a3 = mod_fact(n-k, p, e3);
if(e1 > e2+e3) return 0;
return a1 * mod_inverse(a2*a3%p, p) % p;
} int main(){
fact[0] = 1;
int T; cin >> T;
while(T--){
LL p, m, n;
scanf("%I64d %I64d %I64d", &n, &m, &p);
for(int i = 1; i < p; ++i) fact[i] = fact[i-1] * (LL)i % p;
printf("%I64d\n", mod_comb(n+m, m, p));
}
return 0;
}

第二种:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <unordered_map>
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 10005;
const LL mod = 10000000000007;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int hr[]= {-2, -2, -1, -1, 1, 1, 2, 2};
const int hc[]= {-1, 1, -2, 2, -2, 2, -1, 1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
LL fact[100005];
LL p;
LL quick_pow(LL a, LL b){
LL ans = 1LL;
a %= p;
while(b){
if(b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
} LL C(LL n, LL m){
if(n < m) return 0;
return fact[n] * quick_pow(fact[m]*fact[n-m], p-2) % p;
} LL lucas(LL n, LL m){
if(!m) return 1LL;
return C(n%p, m%p) * lucas(n/p, m/p) % p;
} int main(){
fact[0] = 1;
int T; cin >> T;
while(T--){
LL m, n;
scanf("%I64d %I64d %I64d", &n, &m, &p);
for(int i = 1; i < p; ++i) fact[i] = fact[i-1] * (LL)i % p;
printf("%I64d\n", lucas(n+m, m));
}
return 0;
}

第三种:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <unordered_map>
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 10005;
const LL mod = 10000000000007;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int hr[]= {-2, -2, -1, -1, 1, 1, 2, 2};
const int hc[]= {-1, 1, -2, 2, -2, 2, -1, 1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
LL p;
LL quick_pow(LL a, LL b){
LL ans = 1LL;
a %= p;
while(b){
if(b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
} LL C(LL n, LL m){
if(n < m) return 0;
LL a = 1, b = 1;
while(m){
a = a * n % p;
b = b * m % p;
--m; --n;
}
return a * quick_pow(b, p-2) % p;
} LL lucas(LL n, LL m){
if(!m) return 1LL;
return C(n%p, m%p) * lucas(n/p, m/p) % p;
} int main(){
int T; cin >> T;
while(T--){
LL m, n;
scanf("%I64d %I64d %I64d", &n, &m, &p);
printf("%I64d\n", lucas(n+m, m));
}
return 0;
}

HDU 3037 Saving Beans (数论,Lucas定理)的更多相关文章

  1. HDU 3037 Saving Beans(Lucas定理模板题)

    Problem Description Although winter is far away, squirrels have to work day and night to save beans. ...

  2. HDU 3037 Saving Beans (Lucas法则)

    主题链接:pid=3037">http://acm.hdu.edu.cn/showproblem.php?pid=3037 推出公式为C(n + m, m) % p. 用Lucas定理 ...

  3. hdu 3037 Saving Beans(组合数学)

    hdu 3037 Saving Beans 题目大意:n个数,和不大于m的情况,结果模掉p,p保证为素数. 解题思路:隔板法,C(nn+m)多选的一块保证了n个数的和小于等于m.可是n,m非常大,所以 ...

  4. hdu 3037 Saving Beans Lucas定理

    Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. HDU 3037 Saving Beans(Lucas定理的直接应用)

    解题思路: 直接求C(n+m , m) % p , 由于n , m ,p都非常大,所以要用Lucas定理来解决大组合数取模的问题. #include <string.h> #include ...

  6. Hdu 3037 Saving Beans(Lucus定理+乘法逆元)

    Saving Beans Time Limit: 3000 MS Memory Limit: 32768 K Problem Description Although winter is far aw ...

  7. hdu 3037——Saving Beans

    Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  8. hdu3037 Saving Beans(Lucas定理)

    hdu3037 Saving Beans 题意:n个不同的盒子,每个盒子里放一些球(可不放),总球数<=m,求方案数. $1<=n,m<=1e9,1<p<1e5,p∈pr ...

  9. hdu 3037 Saving Beans

    Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

随机推荐

  1. express 写接口

    实例下载:百度云盘免密码 (): 指注释 一.准备工作 1.安装express npm install express -g npm install express-generator -g 2.初始 ...

  2. Segments--poj3304(判断直线与线段之间的关系)

    http://poj.org/problem?id=3304 给你几条线段  然后 让你找到一条直线让他在这条直线上的映射有一个重合点 如果有这条直线的话  这个重合的部分的两个端点一定是某两条线段的 ...

  3. guava缓存设置return null一直报错空指针

    guava缓存设置return null一直报错空指针 因为缓存不允许返回为空

  4. jmete命令行停止失败的原因分析

    1.在jmeter的master机器上使用如下方式启动远程IP地址2.2.2.2,3.3.3.3上的jmeter slave服务,执行到最后生成报告: sh apache-jmeter-3.1/bin ...

  5. 【python】SHA1 算法

    http://blog.163.com/sh_wenfen/blog/static/99708242007231103936938/

  6. CSS浮动通俗讲解

    首先要知道,div是块级元素,在页面中独占一行,自上而下排列,也就是传说中的流.如下图: 可以看出,即使div1的宽度很小,页面中一行可以容下div1和div2,div2也不会排在div1后边,因为d ...

  7. [Bash] View Files and Folders in Bash

    Sometimes when working at the command line, it can be handy to view a file’s contents right in the t ...

  8. Mongodb for PHP教程之入门安装

    简介: MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据 ...

  9. ubuntu下spring环境搭建

    一.安装JDK 下载官网:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 部署: ...

  10. Android耳机线控具体解释,蓝牙耳机button监听(仿酷狗线控效果)

    转载请注明出处:http://blog.csdn.net/fengyuzhengfan/article/details/46461253 当耳机的媒体按键被单击后.Android系统会发出一个广播.该 ...