G28 求组合数 高精度 线性筛

视频链接:https://www.bilibili.com/video/BV16R4y1X7Fg/

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 10010;
int prim[N], vis[N], cnt;

void get_prim(int n){ //筛素数
  for(int i = 2; i <= n; i ++){
    if(!vis[i]) prim[cnt++] = i;
    for(int j=0; i*prim[j]<=n; j++){
      vis[i*prim[j]] = 1;
      if(i%prim[j] == 0) break;
    }
  }
}
int get(int n,int p){ //n!中p的个数
  int s = 0;
  while(n) s += n/p, n /= p;
  return s;
}
int getps(int n,int m,int p){//C中p的个数
  return get(n,p)-get(m,p)-get(n-m,p);
}
void mul(int C[],int p,int &len){//高精度
  int t = 0;
  for(int i=0; i<len; i++){
    t += C[i]*p;
    C[i] = t%10;
    t /= 10;
  }
  while(t){
    C[len++] = t%10;
    t /= 10;
  }
}
int main(){
  int n, m;
  cin >> n >> m; 
  get_prim(n);
  int C[N], len=1; C[0]=1;
  for(int i=0; i<cnt; i++){
    int p = prim[i];
    int s = getps(n,m,p);
    while(s--) mul(C,p,len); 
  }
  for(int i=len-1; i>=0; i--) 
    printf("%d", C[i]);
  return 0;
}

 

posted @ 2022-10-08 21:35  董晓  阅读(352)  评论(0编辑  收藏  举报