[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; }