HDU 3037 Saving Beans (数论,Lucas定理)
题意:问用不超过 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定理)的更多相关文章
- HDU 3037 Saving Beans(Lucas定理模板题)
Problem Description Although winter is far away, squirrels have to work day and night to save beans. ...
- HDU 3037 Saving Beans (Lucas法则)
主题链接:pid=3037">http://acm.hdu.edu.cn/showproblem.php?pid=3037 推出公式为C(n + m, m) % p. 用Lucas定理 ...
- hdu 3037 Saving Beans(组合数学)
hdu 3037 Saving Beans 题目大意:n个数,和不大于m的情况,结果模掉p,p保证为素数. 解题思路:隔板法,C(nn+m)多选的一块保证了n个数的和小于等于m.可是n,m非常大,所以 ...
- hdu 3037 Saving Beans Lucas定理
Saving Beans Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 3037 Saving Beans(Lucas定理的直接应用)
解题思路: 直接求C(n+m , m) % p , 由于n , m ,p都非常大,所以要用Lucas定理来解决大组合数取模的问题. #include <string.h> #include ...
- Hdu 3037 Saving Beans(Lucus定理+乘法逆元)
Saving Beans Time Limit: 3000 MS Memory Limit: 32768 K Problem Description Although winter is far aw ...
- hdu 3037——Saving Beans
Saving Beans Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- hdu3037 Saving Beans(Lucas定理)
hdu3037 Saving Beans 题意:n个不同的盒子,每个盒子里放一些球(可不放),总球数<=m,求方案数. $1<=n,m<=1e9,1<p<1e5,p∈pr ...
- hdu 3037 Saving Beans
Saving Beans Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
随机推荐
- ubuntu,CentOS永久修改主机名
1.查看主机名 在Ubuntu系统中,快速查看主机名有多种方法: 其一,打开一个GNOME终端窗口,在命令提示符中可以看到主机名,主机名通常位于“@”符号后: 其二,在终端窗口中输入命令:hostna ...
- P2863 [USACO06JAN]牛的舞会The Cow Prom
洛谷——P2863 [USACO06JAN]牛的舞会The Cow Prom 题目描述 The N (2 <= N <= 10,000) cows are so excited: it's ...
- 240.Search in a 2D Matrix II
/* * 240.Search in a 2D Matrix II * 2016-6-17by Mingyang * From left-bottom to right-top * 他这道题目虽说是用 ...
- Spring的AOP AspectJ切入点语法详解(转)
一.Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示 ...
- POJ 3264 Balanced Lineup(RMQ_ST)
题目链接:http://poj.org/problem? id=3264 Description For the daily milking, Farmer John's N cows (1 ≤ N ...
- Office EXCEL 创建图片超链接打不开怎么办 Excel打开图片提示发生了意外错误怎么办
如下图所示,点击超链接提示无法打开指定的文件 如果使用Office打开,则提示发生了意外错误 你需要先把IE浏览器打开,这样就可以打开了,并非是图像的相对位置不正确导致的.
- 在开发过程中,如何在手机上测试vue-cli构建的项目
由于有时候谷歌手机调试与真是的手机环境还是有一定的差距,所以需要在手机上测试项目. 手机上测试vue-cli构建项目方法: 打开项目config/index.js文件,找到module.exports ...
- Fix "Unable to lock the administration directory (/var/lib/dpkg/)" in Ubuntu
While using the apt-get command or the relatively new APT package management tool in Ubuntu Linux or ...
- android抓log
1.Logcat(能截取除了Kernel以外的所有Log信息),连接USB到电脑上,执行如下命令:User版本也可以使用adb logcat –v time >c:\ logcat.txtadb ...
- 【iOS系列】-UIImageView帧动画相关属性介绍
UIImageView帧动画相关属性介绍 1:相关属性: //An array of UIImage objects to use for an animation.存放UIImage对象,会按顺序显 ...