数论
组合数1(递推法)
给定 n 组询问,每组询问给定两个整数 a,b请你输出 C(a,b) mod(10^9+7) 的值。
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 2010, mod = 1e9 + 7;
int c[N][N];
int n;
void init(){
for(int i=0;i<=2000;i++){
for(int j=0;j<=i;j++){
if(!j) c[i][j] = 1;
else c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
}
}
}
int main(){
init();
scanf("%d",&n);
while(n--){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",c[a][b]);
}
return 0;
}
组合数2(预处理)
给定 n 组询问,每组询问给定两个整数 a,b请你输出 C(a,b) mod(10^9+7) 的值。
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100010, mod = 1e9 + 7;
int fact[N],infact[N];
int qmi(int a,int k,int p){
int res = 1;
while(k){
if(k & 1) res = (ll)res * a % p;
a = (ll)a * a % p;
k >>= 1;
}
return res;
}
int main(){
fact[0] = infact[0] = 1;
for(int i=1;i<N;i++){
fact[i] = (ll)fact[i-1] * i % mod;
infact[i] = (ll)infact[i-1] * qmi(i,mod - 2,mod) % mod;
}
int n;
scanf("%d",&n);
while(n--){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",(ll)fact[a] * infact[a-b] % mod * infact[b] % mod);
}
return 0;
}
组合数3(少组数数据量大) Lucas定理
给定 n 组询问,每组询问给定三个整数 a,b,p,其中 p 是质数,请你输出 C(a,b) mod p 的值。
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int qmi(int a,int k,int p){
int res = 1;
while(k){
if(k & 1) res = (ll)res * a % p;
a = (ll)a * a % p;
k >>= 1;
}
return res;
}
int C(int a,int b,int p){
if(b > a) return 0;
int res = 1;
for(int i=1,j=a;i<=b;i++,j--){
res = (ll)res * j % p;
res = (ll)res * qmi(i,p-2,p) % p;
}
return res;
}
int lucas(ll a,ll b,int p){
if(a < p && b < p) return C(a,b,p);
else return (ll)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}
int main(){
int n;
cin >> n;
while(n--){
ll a,b;
int p;
cin >> a >> b >> p;
cout << lucas(a,b,p) << endl;
}
return 0;
}
组合数4(高精度)
请你输出 C(a,b) 的值。
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 5010;
int primes[N],cnt,sum[N];
bool st[N];
void get_primes(int n){
for(int i=2;i<=n;i++){
if(!st[i]) primes[cnt++] = i;
for(int j=0;primes[j]<=n/i;j++){
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;
}
}
}
int get(int n,int p){
int res = 0;
while(n){
res += n / p;
n /= p;
}
return res;
}
vector<int> mul(vector<int> a,int b){
vector<int> c;
int t = 0;
for(int i=0;i<a.size();i++){
t += a[i] * b;
c.push_back(t % 10);
t /= 10;
}
while(t){
c.push_back(t % 10);
t /= 10;
}
return c;
}
int main(){
int a,b;
cin >> a >> b;
get_primes(a);
for(int i=0;i<cnt;i++){
int p = primes[i];
sum[i] = get(a, p) - get(b, p) - get(a-b, p);
}
vector<int> res;
res.push_back(1);
for(int i=0;i<cnt;i++)
for(int j=0;j<sum[i];j++)
res = mul(res,primes[i]);
for(int i = res.size() - 1; i>= 0;i--) printf("%d",res[i]);
puts("");
return 0;
}