数据范围
1≤b≤a≤5000
输入样例:
5 3
输出样例:
10
想法:
a! = a*(a-1)(a-2)…*1
目标:取得a!内 p的指数
p的指数 = 1-a内所有数的质因子p的指数相加,所以需要获取所有数的质因子p的指数。
每一次a/p 算的是 a内质因子内包含 p 的个数,也就是a!中p的指数
相当于取出所有数内pk 中一个 p1
a/p :表示1-a内有多少数含有p因子
每次循环将a!阶乘结果取出一个p
a!
1~a 内的数= k1 * p2 , k2* p2 , k3 * p3 , k4 * p3 * … kn*pk ①
a/p处理以后
1~a 内的数= k1*p , k2*p , k3 * p2 , k4 * p2 * … kn*pk-1 ②
k=a/p就是将①内1-a所有的数抽出一个p,p的个数k res=res+k;
k=a/p2就是将①内1-a所有的数抽出一个p2,p2的个数k res=res+k;
每一层操作永远只在1-a内取 p1 直到取到k次为止,将1-a 的 pk取完。
代码:
#include<iostream>
#include<vector>
using namespace std;
const int N=5010;
int prime[N],st[N],sum[N];
int cnt;
void get_prime(int n){
//线性筛法
for(int i=2;i<=n;i++){
if(!st[i]) prime[cnt++]=i;
for(int j=0;prime[j]<=n/i;j++){
st[prime[j]*i]=true;
if(i%prime[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> res;
int t = 0;
for(int i=0;i<a.size();i++){
t+=a[i]*b;
res.push_back(t%10);
t/=10;
}
while(t){
res.push_back(t%10);
t/=10;
}
return res;
}
int main(){
int a,b;
cin>>a>>b;
//先取得1-a,1-b的质因子
if(a>b)
get_prime(a);
else
get_prime(b);
// //然后获取a,b,a-b内所有质因子的指数
for(int i=0;i<cnt;i++){
int p = prime[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,prime[i]);
}
}
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
return 0;
}