wenbao与组合数
推荐博客:http://blog.csdn.net/u010582475/article/details/47707739
排列组合公式不多说了。。。
卢卡斯定理:
C(n, m)%p == C(n%p, m%p)*C(n/p, m/p),,当m == 0, 递归结束返回1
特例:C(n,m)%2 == 1当且仅当(n&m == m){C(a,b)是奇数当且仅当把a,b二进制表达后b中1的位置是a中1的位置的子集}
范德蒙恒等式:
关于范德蒙推荐博客:http://blog.csdn.net/acdreamers/article/details/31032763
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http://acm.hdu.edu.cn/showproblem.php?pid=3037
卢卡斯定理的应用
经过化解得到求C(n+m, m);;直接跑lks
1 #include <iostream> 2 using namespace std; 3 #define ll long long 4 ll n, m, p; 5 ll a[100009]; 6 void init(){ 7 a[0] = 1LL; 8 for(int i = 1; i <= p; ++i){ 9 a[i] = a[i-1]*i%p; 10 } 11 } 12 ll q_m(ll x, ll y){ 13 ll xx = 1LL; 14 while(y){ 15 if(y&1) xx = xx*x%p; 16 x = x*x%p; 17 y >>= 1; 18 } 19 return xx; 20 } 21 ll C(ll x, ll y){ 22 return x >= y ? a[x]*q_m(a[y]*a[x-y]%p, p-2LL)%p : 0; 23 } 24 ll lks(ll x, ll y){ 25 return y ? C(x%p, y%p)*lks(x/p, y/p)%p : 1LL; 26 } 27 void la(){ 28 init(); 29 printf("%lld\n", lks(n+m, m)); 30 } 31 int main(){ 32 int t; 33 scanf("%d", &t); 34 while(t--){ 35 scanf("%lld%lld%lld", &n, &m, &p); 36 la(); 37 } 38 return 0; 39 }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
范德蒙恒等式的应用:
裸的
http://codeforces.com/contest/785/problem/D
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 #define ll long long 5 const int maxn = 200009; 6 const ll Mod = 1e9+7; 7 char str[maxn]; 8 ll p[maxn], sum = 0, x, num; 9 void init(){ 10 p[0] = p[1] = 1; 11 for(int i = 2; i < maxn; ++i){ 12 p[i] = p[i-1]*i%Mod; 13 } 14 } 15 ll q_m(ll x, ll y){ 16 ll sum = 1; 17 while(y){ 18 if(y&1) sum = sum*x%Mod; 19 x = x*x%Mod; 20 y >>= 1; 21 } 22 return sum; 23 } 24 ll C(ll x, ll n){ 25 return p[n]*q_m(p[x]*p[n-x]%Mod, Mod-2)%Mod; 26 } 27 int main(){ 28 init(); 29 scanf("%s", str); 30 int len = strlen(str); 31 for(int i = 0; str[i]; ++i){ 32 x += (str[i] == ')'); 33 } 34 for(int j = 0; j < len; ++j){ 35 if(str[j] == ')') --x; 36 else{ 37 sum = (sum + C(x-1, x+(num++)))%Mod; 38 } 39 } 40 printf("%lld\n", sum); 41 return 0; 42 }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
只有不断学习才能进步!