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;
}
posted @ 2018-08-05 21:02  lokiii  阅读(182)  评论(0编辑  收藏  举报