POJ 3421 - X-factor Chains(数学)

来源:互联网 发布:非洲提督知乎 编辑:程序博客网 时间:2024/05/23 17:19

题目:

http://poj.org/problem?id=3421

题意:

求n的因子链,使得前一个数整除后一个数,求出链的最大长度以及这样的链的数量。

思路:

n可以分解成质因子的乘积,n = p1^a1 * p2^a2 * p3^a2.....pn^an.

最大长度ans = a1+a2+a3...+an,

链的数量 = ans!/ a1! * a2! * ...* an!.   (如果我把所有质因子都排列好,从前到后乘起来就可以看成是一条新的链。

这样的思路还是会超时严重,应该预处理得到质数表。

CODE:

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;typedef long long ll;const ll maxn = (1<<20)+5;bool vis[maxn];int pri[85000], k;ll f[25];ll n;void isprime(){    k = 0;    //memset(vis, 0, sizeof(vis));    for(int i = 2; i < maxn; ++i) {        if(vis[i]) continue;        pri[k++] = i;        for(int j = i+i; j < maxn; j+=i) vis[j] = 1;    }}void work(){    int cnt, ans = 0;    ll under = 1;    for(ll i = 0; i < k; ++i) {        if(n % pri[i] == 0) {            cnt = 0;            while(n%pri[i] == 0) {                n /= pri[i];                cnt++;            }            under *= f[cnt];            ans += cnt;        }        if(n == 1) break;        if(!vis[n]) {            ans++;            break;        }    }    printf("%d %I64d\n", ans, f[ans]/under);}int main(){    isprime();    f[1] = 1;    for(int i = 2; i <= 20; i++) {        f[i] = f[i - 1]*i;    }    while(~scanf("%lld", &n)) {        work();    }    return 0;}


0 0
原创粉丝点击