HDU5525(乘法原理)

来源:互联网 发布:linux 通配符 编辑:程序博客网 时间:2024/06/02 20:36

首先把每一个数拆成质因数的乘积,把对应的次数累计起来。然后设第i个质因数的指数累计的和是ai,那么i^t(0<=t<=ai)这个因子出现的次数就是(1+a1)*(1+a2)*...*(1+ak)/(1+ai)。

然后各种取模。

#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <iostream>using namespace std;#define maxn 111111long long mod = 1e9+7;long long num[maxn], a[maxn];vector <int> fac[maxn];long long pre[maxn], last[maxn]; //前缀乘积,后缀乘积bool is_prime[maxn];long long prime[maxn], cnt;long long n;long long kk;long long qpow (long long a, long long b) {    if (b == 0)        return 1;    long long ans = qpow (a, b/2);    ans = ans*ans%mod;    if (b&1) {        ans = ans*a%mod;    }    return ans%mod;}long long get (long long cur, int pos, int tot) {    long long ans = 1;    long long mod2 = mod-1;    if (num[cur]&1) {        ans = (num[cur]+1)/2%mod2*(num[cur]%mod2)%mod2;    }    else ans = (num[cur]/2)%mod2*((num[cur]+1)%mod2) % mod2;    if (tot == 1) {        return ans;    }    else if (pos == 0) {        ans = ans*last[1]%mod2;    }    else if (pos == tot-1) {        ans = ans*pre[pos-1]%mod2;    }    else ans = ans*pre[pos-1]%mod2*last[pos+1]%mod2;    return ans;}void solve () {    long long ans = 1;    unsigned long long gg = 1;    int tot = 0;    for (int i = 0; i < cnt && prime[i] <= n; i++, tot++) {    }    for (int i = 0; i < tot; i++) {        pre[i] = (i == 0 ? (num[prime[i]]+1)%(mod-1) : (num[prime[i]]+1)%(mod-1)*pre[i-1]%(mod-1));    }    for (int i = tot-1; i >= 0; i--) {        last[i] = (i == tot-1 ? (num[prime[i]]+1)%(mod-1) : (num[prime[i]]+1)%(mod-1)*last[i+1]%(mod-1));    }    for (int i = 0; i < tot; i++) {        long long cur = prime[i];        ans *= qpow (cur, get (cur, i, tot));        ans %= mod;    }    printf ("%lld\n", ans);}int main () {    //freopen ("in", "r", stdin);    cnt = 0;    memset (is_prime, 1, sizeof is_prime);    for (int i = 2; i <= 100000; i++) {        if (is_prime[i]) {            prime[cnt++] = i;            for (int j = i+i; j <= 100000; j += i) {                is_prime[j] = 0;            }        }    }    for (int i = 1; i <= 100000; i++) {        fac[i].clear ();    }    for (int i = 1; i <= 100000; i++) {        for (int j = i; j <= 100000; j += i) {            fac[j].push_back (i);        }    }    while (scanf ("%lld", &n) == 1) {        memset (num, 0, sizeof num);        for (int i = 1; i <= n; i++) {            scanf ("%lld", &a[i]);            for (int j = 1; j < fac[i].size (); j++) {                long long cur = fac[i][j];                long long tot = 0, m = i;                while (m%cur == 0) {                    tot += a[i];                    m /= cur;                }                num[cur] += tot;            }        }        solve ();    }    return 0;}


0 0
原创粉丝点击