a、b是非負整數,p是質數。ab寫成p進製:a=a[n]a[n-1]…a[0],b=b[n]b[n-1]…b[0]。
則組合數c(a,b)與c(a[n],b[n])c(a[n-1],b[n-1])…*c(a[0],b[0]) modp同餘
即:lucas(n,m,p)=c(n%p,m%p)*lucas(n/p,m/p,p)
然而如果p很大c(n%p,m%p)也是會溢位的,這裡要用到m!(n-m)!的逆元。(雖然我並不知道逆元什麼東西 /(ㄒoㄒ)/~~ 感覺自己差的太多)
根據費馬小定理(並不懂這個定理怎麼證明的 (@﹏@)~):
已知(a, p) = 1,則 ap-1 ≡ 1 (mod p), 所以 a*ap-2 ≡ 1 (mod p)。
也就是 (m!(n-m)!)的逆元為 (m!(n-m)!)p-2
下面是模板
#define ll long long
ll fac[100003];
void init(ll p)
}ll pow(ll a, ll b, ll p)
a = (a*a)%p;
b >>= 1;
}return ret;
}ll lucas(ll a, ll b, ll p)
return ret;
}
hdu 3037
計算c(n+m,m)%p
#include
#define ll long long
using namespace std;
ll fac[100003];
void init(ll p)
}ll pow(ll a, ll b, ll p)
a = (a*a)%p;
b >>= 1;
}return ret;
}ll lucas(ll a, ll b, ll p)
return ret;
}int main()
return
0;
}
hdu 4349 xiao ming』s hope
lucas定理推廣
#include
#define ll long long
#define n 1005
using
namespace
std;
int main()
printf("%lld\n", (long
long)pow(2, t));
}return
0;}
組合數取模介紹 Lucas定理介紹
1.當n,m都很小的時候可以利用楊輝三角直接求。c n,m c n 1,m c n 1,m 1 const int maxn 1e5 10 ll fac maxn 階乘打表 void init ll p 此處的p應該小於1e5,這樣lucas定理才適用 ll pow ll a,ll b,ll m a...
Lucas 組合數取模
組合數取模就是求 cn mmod p cmn modp 的值,當然根據n,m,p n,m p 的取值範圍不同,採取的方法也不一樣。p p 比較大就只能乙個乙個算如 ll c one by one ll n,ll m 組合數乙個乙個算但是不是很大的要預先處理好階乘 數很大需要逆元 typedef lo...
組合數取模(楊輝三角 Lucas定理 模合數)
1 1 m n 1000 和 1 p 10 9 p可以是任何數 這個問題比較簡單,組合數的計算可以靠 楊輝三角 那麼由於和的範圍小,直接兩層迴圈即可。long long c maxn maxn void comb int n,int m,int p 1 m n 10 18 和 2 p 10 5 p ...