题意:问用不超过 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. Delphi:解决重绘造成的窗体闪烁问题

    解决窗体闪烁问题 具体代码: 1.在声明窗体类时加入:   private     procedure CreateParams(var Params: TCreateParams); overrid ...

  2. 【Java源码】集合类-优先队列PriorityQueue

    一.类继承关系 public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serial ...

  3. CD-----UVa624(01背包+输出路径)

      CD  You have a long drive by car ahead. You have a tape recorder, but unfortunately your best musi ...

  4. Topcoder 658Div2

    补题风向标——>> 假装题意知道 A:暴力合成一遍了 n=s.size(); m=t.size(); ss+=s; tt+=t; if (ss==tt) or not; B:题意是给定 1 ...

  5. powerDigner使用

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...

  6. 109.Convert sorted list to BST

    /* * 109.Convert sorted list to BST * 2016.12.24 by Mingyang * 这里的问题是对于一个链表我们是不能常量时间访问它的中间元素的. * 这时候 ...

  7. Spring MVC中 log4j日志文件配置相对路径

    log4j和web.xml配置webAppRootKey 的问题 1 在web.xml配置 <context-param>  <param-name>webAppRootKey ...

  8. eclipse工程设置项目jre

    Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.当我们导入已经存在项目或者通过svn引入项目时经常出现红叉叉的情 ...

  9. win7右下角无线网图标显示未连接,但是实际上已连接上,也能上网

    首先,要确实是不是服务启动的问题,方法很简单,重新启动电脑就可以. 如果问题依旧,那么按下Win+R快捷键,输入“services.msc”,打开服务界面. 然后会看到右侧窗口出现好多设置项,找到“R ...

  10. 转帖:对linux中半增加半连接数量和防止服务器被dos攻击

    .增大队列SYN最大半连接数 在Linux中执行命令"sysctl -a|grep net.ipv4.tcp_max_syn_backlog",在返回的"net.ipv4 ...