[hdu5525 Product]暴力

题意:给定n和a[],令N = ∏(1≤i≤n)ia[i],求N的所有约数的积(取模1e9+7)

思路:

  • 假定N因式分解后的结果是2p1*3p2*5p3*...,如何计算答案呢?
  • 单独看2p1这一项,考虑它所有的贡献,它在N的约数里面总共会出现P=(p2+1)*(p3+1)*...次,由于是求乘积,而且2的指数可以取[0,p1],那么它总共产生的答案为(20)P*(21)P*(22)P*...=2(p1+1)*p1/2 * P=2p1*M/2,其中M=(p1+1)*(p2+1)*(p3+1)*...
  • 因此答案就是2p1*M/2*3p2*M/2*5p3*M/2*...
  • 所以首先把N的因式分解式求出来,然后按照上述公式求解即可
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define pb(x) push_back(x)
#define mp(x, y) make_pair(x, y)
#define all(a) (a).begin(), (a).end()
#define mset(a, x) memset(a, x, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(b))
#define cas() int T, cas = 0; cin >> T; while (T --)
template<typename T>bool umax(T&a, const T&b){return a<b?(a=b,true):false;}
template<typename T>bool umin(T&a, const T&b){return b<a?(a=b,true):false;}
typedef long long ll;
typedef pair<int, int> pii;

#ifndef ONLINE_JUDGE
    #include "local.h"
#endif

const int mod = 1e9 + 7;
const int N = 1e5 + 7;

vector<int> prime;
ll total[N];
bool used[N];
int a[N], ID[N];

void getPrime() {
    for (ll i = 2; i < N; i ++) {
        if (!used[i]) {
            prime.pb(i);
            for (ll j = i * i; j < N; j += i) used[j] = true;
        }
    }
    for (int i = 0; i < prime.size(); i ++) {
        ID[prime[i]] = i;
    }
}

pair<vector<int>, vector<int> > Y[N];

vector<int> fac;
vector<int> cnt;

void div(int x) {
    if (x > 2 && !used[x]) {
        fac.pb(x);
        cnt.pb(1);
        return;
    }
    for (int i = 0; i < prime.size() && prime[i] <= x;  i ++) {
        int c = 0;
        while (x % prime[i] == 0) {
            c ++;
            x /= prime[i];
        }
        if (c) {
            fac.pb(prime[i]);
            cnt.pb(c);
        }
        if (x < prime[i]) break;
    }
}

ll powermod(ll a, ll n, ll mod) {
    ll ans = 1;
    while (n) {
        if (n & 1) ans = ans * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return ans;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    getPrime();
    for (int i = 1; i < N; i ++) {
        fac.clear();
        cnt.clear();
        div(i);
        Y[i] = mp(fac, cnt);
    }
    int n;
    while (cin >> n) {
        for (int i = 1; i <= n; i ++) {
            scanf("%d", a + i);
        }
        mset(total, 0);
        for (int i = 1; i <= n; i ++) {
            for (int j = 0; j < Y[i].first.size(); j ++) {
                int id = ID[Y[i].first[j]];
                total[id] += Y[i].second[j] * a[i];
            }
        }
        ll M = 1, ans = 1;
        ll Mod = 2 * mod - 2;
        for (int i = 0; i < prime.size(); i ++) {
            M = M * ((total[i] + 1) % Mod) % Mod;
        }
        for (int i = 0; i < prime.size(); i ++) {
            ans = ans * powermod(prime[i], M * (total[i] % Mod) % Mod / 2, mod) % mod;
        }
        cout << ans << endl;
    }
    return 0;
}

  

posted @ 2015-10-31 22:56  jklongint  阅读(172)  评论(0编辑  收藏  举报