poj 2992 Divisors 筛法 算术基本定理
Divisors
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11340 | Accepted: 3376 |
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
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.
Sample Input
5 1 6 3 10 4
Sample Output
2 6 16
题意:求一个组合数的因子个数
思路:算术基本定理;
#include<iostream> #include<cmath> #include<cstring> #include<queue> #include<cstdio> #define LL long long #define M 432 using namespace std; struct m { int a[83]; } q[432]; bool visit[M]; int p[M]; int np=0; void ddd() { memset(visit,1,sizeof(visit)); for(int i=2; i<M; ++i) { if(visit[i]==1) { p[np++]=i; for(int j=i*i; j<M; j+=i) { visit[j]=0; } } } } void iii() { int t,i,w,j,d; for(i=0; i<83; i++) q[0].a[i]=0; for(i=1; i<=432; i++) { t=i; for(w=0; w<=82; w++) q[i].a[w]=q[i-1].a[w]; for(j=0; p[j]<=i; j++) { while(t%p[j]==0) { q[i].a[j]++; t/=p[j]; } if(t==1) break; } } } int main() { ddd(); iii(); LL ans; int i,b,t,a; while(~scanf("%d %d",&a,&b)) { t=a-b; ans=1; int x=a>82?82:a; for(i=0; i<=x; i++) ans*=(1+(long long )q[a].a[i]-q[b].a[i]-q[t].a[i]); printf("%lld\n",ans); } return 0; }