求组合数

1:暴力求法,n<15

int C(int n,int m) {
    int mod=10007;
    int ans=1;
    for(int i=n;i>=(n-m+1);i--) ans*=i;
    while(m) ans/=m--;
    return ans%mod;
}
View Code

2:打表 n<1e4

int C[1005][1005];
void init() {
    for(int i=0;i<=1005;i++) C[0][i]=0,C[i][0]=1;
    for(int i=1;i<=1005;i++) {
        for(int j=1;j<=1005;j++) 
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    }
}
View Code
ll c[100010][5];
void init() {
    c[0][0]=1;
    for(int i=1;i<=100001;i++) {
        c[i][0]=1;
        for(int j=1;j<=4;j++)
        c[i][j]=(c[i-1][j]+c[i-1][j-1]);
    }
}
View Code

3:质因数分解 

大数:

#include 
using namespace std;
typedef long long ll;

const int MAXN = 5005;
bool isp[MAXN];
int cnt=0;
int pre[MAXN],rat[MAXN];
void prime(int n) {
    for(int i=2;i<=n;i++) {
        if(!isp[i]) pre[cnt++]=i;
        for(int j=0;j) {
            isp[i*pre[j]]=true;
            if(!(i%pre[j])) break;
        }
    }
}
int rate(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>p;
    int t=0;
    for(int i=0;i) {
        t+=a[i]*b;
        p.push_back(t % 10);
        t/=10;
    }
    while(t) {
        p.push_back(t%10);
        t/=10;
    }
    return p;
}
int main( ) {
    int a,b;
    scanf("%d%d",&a,&b);
    prime(a);
    for(int i=0;i) {
        int p=pre[i];
        rat[i]=rate(a,p)-rate(b,p)-rate(a-b,p);
    }
    vector<int>res;
    res.push_back(1);
    for(int i=0;i) {
        for(int j=0;j)
            res=Mul(res,pre[i]);
    }
    for(int i=res.size()-1;~i;i--) printf("%d", res[i]);
    return 0;
}
View Code

非大数:

#include 
const int maxn=1000000;
#include 
using namespace std;
typedef long long ll;
bool arr[maxn+1]={false};
vector<int> produce_prim_number() {
    vector<int> prim;
    prim.push_back(2);
    int i,j;
    for(i=3;i*i<=maxn;i+=2) {
        if(!arr[i]) {
            prim.push_back(i);
            for(j=i*i;j<=maxn;j+=i) arr[j]=true;
        }
    }
    while(i<maxn) {
        if(!arr[i]) prim.push_back(i);
        i+=2;
    }
    return prim;
}
int cal(int x,int p) {
    int ans=0;
    ll rec=p;
    while(x>=rec) {
        ans+=x/rec;
        rec*=p;
    }
    return ans;
}
int pow(ll n,int k,int M) {
    ll ans=1;
    while(k) {
        if(k&1) ans=(ans*n)%M;
        n=(n*n)%M;
        k>>=1;
    }
    return ans;
}
int combination(int n,int m) {
    const int M=10007;
    vector<int> prim=produce_prim_number();
    ll ans=1;
    int num;
    for(int i=0;i) {
        num=cal(n,prim[i])-cal(m,prim[i])-cal(n-m,prim[i]);
        ans=(ans*pow(prim[i],num,M))%M;
    }
    return ans;
}
int main() {
        int m,n;
        while(~scanf("%d%d",&m,&n),m&&n) {
            printf("%d\n",combination(m,n));
        }
        return 0;
}
View Code

4:Lucas定 (long long) n和m较大,但是p为素数的时候,求 c(n,m) mod p

#include 
using namespace std;
typedef long long ll;
#define mod 1000000007
ll ksm(ll a,ll b) {
    ll ans=1;
    while(b) {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
ll zuheshu(ll a,ll b) {
    if(areturn 0;
    if(a==b) return 1;
    ll u=1,d=1;
    for(ll i=1;i<=a;i++) u=u*i%mod;
    for(ll i=1;i<=b;i++) d=d*i%mod;
    for(ll i=1;i<=a-b;i++) d=d*i%mod;
    return u*ksm(d,(mod-2))%mod;
}

int main( ) {
    ll n,m;;
    while(cin>>n>>m) {
        cout<endl;
    }
    return 0;
}
View Code

 5: long long

#include 
using namespace std;
typedef long long ll;
ll C(ll x, ll y) {
    ll a=x+y;
    ll b=min(x,y);
    double t=1.0;
    while(b>0) t*=(double)(a--)/(double)(b--);
    t+=0.5;
    return (ll)t;
}
int main( ) {
    ll n,m;
    while(cin>>n>>m) {
        if(n==0&&m==0) break;
        cout<endl;
    }
    return 0;
}
View Code

 

你可能感兴趣的:(求组合数)