#include<iostream>#include<algorithm>#include<cmath>
using namespace std;constint N =2e3+10, mod =1e9+7;int c[N][N];voidinit(){for(int i =0; i < N;++ i)for(int j =0; j <= i;++ j)if(j ==0) c[i][j]=1;//i == j的情况可以通过前面处理好的递推出来else c[i][j]=(c[i -1][j]+ c[i -1][j -1])% mod;}voidsolve(){int n;
cin >> n;init();while(n --){int a, b;
cin >> a >> b;
cout << c[a][b]<< endl;}}int32_tmain(){
ios::sync_with_stdio(0);
cin.tie(0);int T =1;//cin >> T;while(T --)solve();return0;}
AcWing 886. 求组合数 II
运用组合数的定义,即最基本的运算公式。
基本运算公式中含有除法,我们想把除法变成乘法。
前面说了除法变乘法,本题正好有取模预算,取模运算下除法变乘法可以用欧拉函数扩展。
模又是质数,可以用费马定理,费马定理可以用快速幂将N优化为logN复杂度
#include<iostream>#include<algorithm>#include<cmath>
using namespace std;typedeflonglong LL;constint N =1e5+10, mod =1e9+7;int fact[N];//fact[i]表示i的阶乘int infact[N];//infact[i]表示i阶乘的逆元,可以由infact[i - 1] * i的逆元获得intqmi(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;}voidsolve(){int n;
cin >> n;
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;}while(n --){int a, b;
cin >> a >> b;printf("%d\n",(LL)fact[a]* infact[b]% mod * infact[a - b]% mod);}}int32_tmain(){
ios::sync_with_stdio(0);
cin.tie(0);int T =1;//cin >> T;while(T --)solve();return0;}
AcWing 887. 求组合数 III
#include<iostream>#include<algorithm>#include<cmath>
using namespace std;typedeflonglong LL;intqmi(int a,int k,int p){
LL res =1;while(k){if(k &1) res = res * a % p;
a =(LL)a * a % p;
k >>=1;}return res;}intC(LL a, LL b,int p)//好坑,a和b可能是LL{if(a < b)return0;if(b > a - b) b = a - b;//Ca b = Ca a - b,可以自己举个例子int x =1, y =1;for(int i =0; i < b;++ i)//就是C^b^~a~ = a! / ((a-b)!*b!){
x =(LL)x *(a - i)% p;
y =(LL)y *(i +1)% p;}return(LL)x *qmi(y, p -2, p)% p;//p一定为质数}intlucas(LL a, LL b,int p){if(a < p && b < p)returnC(a, b, p);return(LL)C(a % p, b % p, p)*lucas(a / p, b / p, p)% p;}voidsolve(){int n;
cin >> n;
LL a, b;int p;while(n --){
cin >> a >> b >> p;//好坑,a和b可能是LL
cout <<lucas(a, b, p)<< endl;}}int32_tmain(){
ios::sync_with_stdio(0);
cin.tie(0);int T =1;//cin >> T;while(T --)solve();return0;}
AcWing 888. 求组合数 IV
#include<iostream>#include<algorithm>#include<cmath>
using namespace std;constint N =5e3;int primes[N], cnt;int sum[N];
bool st[N];voidinit(int a)//初始化获得1-a之间所有的质数,数论里面学过 a一定可以分解成质因数的乘积{for(int i =2; i <= a;++ i){if(!st[i]) primes[cnt++]= i;for(int j =0; primes[j]<= a / i;++ j){
st[i * primes[j]]= true;if(i % primes[j]==0)break;}}}intget(int x,int p)//获得每个质因数的数量{int res =0;while(x){
res += x / p;
x /= p;}return res;}
vector<int>mul(vector<int> a,int b)//高精度乘法{int t =0;
vector<int> C;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;}voidsolve(){int a, b;
cin >> a >> b;init(a);for(int i =0; i < cnt;++ i)//计算结果中的所有质因数的数量
sum[i]=get(a, primes[i])-get(a - b, primes[i])-get(b, primes[i]);
vector<int> res;
res.push_back(1);for(int i =0; i < cnt;++ i)for(int j =1; j <= sum[i];++ j)
res =mul(res, primes[i]);for(int i = res.size()-1; i >=0;-- i) cout << res[i];}int32_tmain(){
ios::sync_with_stdio(0);
cin.tie(0);int T =1;//cin >> T;while(T --)solve();return0;}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;public class A02_Generic : MonoBehaviour
{[ContextMenu("测试Start")]// Start is called before the first frame updatevoid Start(){Person…