bzoj 4807: 車【组合数+高精+线性筛】
设n>m,答案是\( C_n^m \),然后高精就行了
具体做法是先把指数筛出来,然后对每个数因数分解,记录质因子个数,最后被除数减去除数质因子个数,把剩下的质因子乘起来就行了
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1000005;
int n,m,q[N],p[N],tot,c[N];
struct gj
{
int a[55];
gj operator * (const int &b) const
{
gj r;
for(int i=1;i<=50;i++)
r.a[i]=0;
for(int i=1;i<=50;i++)
{
r.a[i]+=a[i]*b;
r.a[i+1]+=r.a[i]/10;
r.a[i]%=10;
}
return r;
}
}ans;
void wk(int x,int f)
{
while(x!=1)
c[p[x]]+=f,x/=p[x];
}
int main()
{
scanf("%d%d",&n,&m);
if(n<m)
swap(n,m);
for(int i=2;i<=n;i++)
{
if(!p[i])
{
p[i]=i;
q[++tot]=i;
}
for(int j=1;j<=tot&&i*q[j]<=n;j++)
{
p[i*q[j]]=q[j];
if(i%q[j]==0)
break;
}
}
for(int i=1;i<=n-m;i++)
wk(i,-1);
for(int i=m+1;i<=n;i++)
wk(i,1);
ans.a[1]=1;
for(int i=2;i<=n;i++)
for(int j=1;j<=c[i];j++)
ans=ans*i;
int len=50;
while(ans.a[len]==0)
len--;
for(int i=len;i>=1;i--)
printf("%d",ans.a[i]);
return 0;
}