您的位置:首页 > 其它

POJ 2992 求组合数的因子个数

2015-09-10 20:36 423 查看
求C(n,k)的因子个数

C(n,k) = (n*(n-1)*...*(n-k+1))/(1*2*...*k) = p1^k1 * p2^k2 * ... * pt^kt

这里只要计算出分子中素数因子个数减去分母中的个数

然后每一种因子都有 (cnt+1)种取的可能,乘一下就出来了

但是不能逐个因子分解,试了两次都错了,后来初始的时候,先将这432个数提前预处理分解好保存到vector中

然后用的时候直接提取就行

不然会因为数据量太大超时的

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <vector>

using namespace std;
#define ll long long
#define N 500
#define pii pair<int,int>
int cnt[N+5] , prime[N+5] , tot;
bool check[N+5];
vector<pii> v
;

void init()
{
check[1] = true;
for(int i=2 ; i<=N ; i++)
{
if(!check[i]) prime[tot++] = i;
for(int j=i+i ; j<=N ; j+=i) check[j]=true;
}
}

void fenjie(int x)
{
int tmp = x;
for(int i=0 ; i<tot ; i++){
if(prime[i]>x) break;
int cnt = 0;
while(x%prime[i]==0){
x/=prime[i];
cnt++;
}
if(cnt) v[tmp].push_back(make_pair(prime[i] , cnt));
}
if(x>1) v[tmp].push_back(make_pair(x , 1));
}

void solve(int n , int k)
{
memset(cnt , 0 , sizeof(int)*(n+1));
for(int i=1 , up=n , dn=1 ; i<=k ; i++ , up-- , dn++){
int l1 = v[up].size() , l2 = v[dn].size();
for(int i=0 ; i<l1 ; i++) cnt[v[up][i].first] += v[up][i].second;
for(int i=0 ; i<l2 ; i++) cnt[v[dn][i].first] -= v[dn][i].second;
}
ll ret = 1;
for(int i=0 ; i<tot ; i++){
if(prime[i]>n) break;
ret *= (cnt[prime[i]]+1);
}
printf("%I64d\n" , ret);
}

int main() {
// freopen("a.in" , "r" , stdin);
// freopen("out.txt" , "w" , stdout);
init();
for(int i=1 ; i<=432 ; i++) {v[i].clear();fenjie(i);}
int n , k;
while(~scanf("%d%d" , &n , &k)){
solve(n , k);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: