Lucas定理 組合數取模

2021-07-11 04:53:38 字數 1329 閱讀 7340

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 ...