bzoj4807【题解】車 组合数 高精 线性筛
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4807
老师给的标签是数学。
本以为很难弄。
结果发现有摆最多个数这个限制。
自然想到答案就为对角线这样的排列。
自然也就是,C(max(n,m),min(n,m))
主要在于要保留50位。
必然是高精。
那么为了避免高精除法。
分解质因数。
上下约分再进行高精乘法。
代码如下:
/************************************************************** Problem: 4807 User: ChrisK Language: C++ Result: Accepted Time:304 ms Memory:13012 kb ****************************************************************/ #include<bits/stdc++.h> using namespace std; const int maxn=1000010; int n,m,tot,l=50; int p[maxn],q[maxn]; int c[maxn]; struct node{ int s[60]; node operator * (const int &b) const{ node q; for(int i=1;i<=50;i++) q.s[i]=0; for(int i=1;i<=50;i++){ q.s[i]+=s[i]*b; q.s[i+1]+=q.s[i]/10; q.s[i]%=10; } return q; } }ans; void chai(int x,int y){ while(x!=1){ c[p[x]]+=y,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++) chai(i,-1); for(int i=m+1;i<=n;i++) chai(i,1); ans.s[1]=1; for(int i=2;i<=n;i++) for(int j=1;j<=c[i];j++) ans=ans*i; while(ans.s[l]==0) l--; for(int i=l;i>=1;i--) printf("%d",ans.s[i]); puts(""); return 0; }