poj2992 divisors 求組合數的約數個數,階乘的質因數分解
阿新 • • 發佈:2018-05-23
TP iostream 約數個數 PE printf for tinc 階乘 BE Your task in this problem is to determine the number of divisors of Cnk. Just for fun -- or do you need any special reason for such a useful computation?
For each instance, output a line containing exactly one integer -- the number of distinct divisors of Cnk. For the input instances, this number does not exceed 2 63 - 1.
Input
The input consists of several instances. Each instance consists of a single line containing two integers n and k (0 ≤ k ≤ n ≤ 431), separated by a single space.Output
Sample Input
5 1 6 3 10 4
Sample Output
2 6 16
思路:計算約數個數的時候,可以類比數的唯一分解求約數個數;
s=2^p1*3^p2*5^p3*-----
num=(p1+1)*(p2+1)*(p3+1)*....
如果求分數類型的約數個數...
可以分解質因數之後在上面的個數-下面的個數
即s__=2^(p1-p1_)*3^(p2-p2_)*----
num=(p1-p1_+1)*(p2-p2_+1)*(p3-p3_+1)*---
階乘的質因數分解:
int cal(int n,int p) if(n<p)return 0;else return n/p+cal(n/p,p);
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int prime[500];bool vis[500]; typedef long long ll;int cnt; void init(){ for(int i=2;i<=431;i++){ if(!vis[i]) for(int j=i*2;j<=431;j+=i) vis[j]=1; } for(int i=2;i<=431;i++){ if(!vis[i]) prime[++cnt]=i; } } int num1[500],num2[500]; int cal(int n,int p){ if(n<p) return 0; else return n/p+cal(n/p,p); } int main(){ init();int n,m; //std::ios::sync_with_stdio(false);cin.tie(0); //for(int i=1;i<=83;i++) cout<<prime[i]<<endl; while(~scanf("%d%d",&n,&m)){ ll ans=1; memset(num1,0,sizeof(num1)); memset(num2,0,sizeof(num2)); for(int i=1;prime[i]<=n&&i<=cnt;i++){ num1[i]=cal(n,prime[i]); num2[i]=cal(m,prime[i])+cal(n-m,prime[i]); ans*=(num1[i]-num2[i]+1); //cout<<ans<<endl; } printf("%lld\n",ans); } return 0; }
poj2992 divisors 求組合數的約數個數,階乘的質因數分解