POJ 2992 Divisors(求組合數因子個數)
阿新 • • 發佈:2019-01-29
Divisors
Description 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?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 Source |
題意:求C(n,k)的因子個數。
題解:C(n,k)=n!/k!/(n-k)!,直接將所有階乘的數分解出所有素因數然後統計一下
然後套用因數個數公式就好 (p1+1)*(p2+1)*(p3+1)*...*(pn+1)
題目很簡單,然而卡時間,500*50*50都卡??
好吧,預處理一下就OK了。。。。。
定義dp[i][j]:表示i的階乘裡有幾個素數j。
#include<set> #include<map> #include<stack> #include<queue> #include<vector> #include<string> #include<time.h> #include<math.h> #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<algorithm> #include<functional> using namespace std; #define ll long long #define inf 1000000000 #define mod 1000000007 #define maxn 50500 #define lowbit(x) (x&-x) #define eps 1e-9 ll a[505]={1,1},b[500]; ll dp[450][450],cnt; void init() { ll i,j; for(i=2;i<=432;i++) { if(a[i]) continue; b[++cnt]=i; for(j=i*i;j<=432;j+=i) a[j]=1; } for(i=2;i<=432;i++) { for(j=1;b[j]<=i && j<=cnt;j++) { ll tmp=i,res=0; while(tmp) tmp/=b[j],res+=tmp; dp[i][b[j]]=res; } } } int main(void) { init(); ll i,x,y; while(scanf("%lld%lld",&x,&y)!=EOF) { ll ans=1; for(i=1;b[i]<=x && i<=cnt;i++) { ll tmp=dp[x][b[i]]-dp[y][b[i]]-dp[x-y][b[i]]; ans=ans*(tmp+1); } printf("%lld\n",ans); } return 0; }