題目來源:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=644&pid=1003
前面用奇偶性約掉2,後面處理前綴積和後綴積。php
WA了好久的地方:在約掉2以前不能模(mod-1)
ios
#include <iostream> #include <cstring> #include <cstdio> #include <vector> using namespace std; typedef long long LL; const int N = 100001; LL Mod = 1000000007; LL mod = Mod - 1; char vis[N]; int prime[N]; vector<int> G[N]; int tot = 0; void init_prime() { memset(vis, 0, sizeof(vis)); for(int i=2; i<N; i++) { if(!vis[i]) { prime[++tot] = i; for(int j=i; j<N; j+=i) { vis[j] = 1; G[j].push_back(i); } } } } LL quick(LL a, LL b) { LL c = 1; while(b) { if(b&1) c = c * a % Mod; b >>= 1; a = a * a % Mod; } return c; } int a[N]; LL num[N]; //素數i的個數 LL pre[N], suf[N]; int main() { init_prime(); int i, j, k, m, n; while(scanf("%d", &n) == 1) { for(i=1; i<=n; i++) scanf("%d", a+i); memset(num, 0, sizeof(num)); for(i=1; i<=n; i++) { for(j=0; j<G[i].size(); j++) { int tp = 0, x = i; while(x%G[i][j] == 0) { tp ++; x /= G[i][j]; } num[G[i][j]] += a[i] * tp; } } ///處理(p1+1)*(p2+1)*...*(px+1)的前綴積和後綴積 pre[0] = 1; for(int i=1; i<=tot; i++) { pre[i] = pre[i-1]; if(num[prime[i]]) pre[i] = pre[i] * (num[prime[i]] % mod +1) % mod; } suf[tot+1] = 1; for(int i=tot; i>=1; i--) { suf[i] = suf[i+1]; if(num[prime[i]]) suf[i] = suf[i] * (num[prime[i]] % mod +1) % mod; } /*---------------------------------------------*/ LL ans = 1; for(int i=1; i<=tot; i++) { LL tmp, p = num[prime[i]]; if(p & 1) tmp = p % mod * (((p+1)>>1) % mod) % mod; else tmp = (p>>1) %mod * ((p+1) % mod) % mod; ans = ans * quick(prime[i], tmp * pre[i-1] % mod * suf[i+1] % mod) % Mod; } printf("%I64d\n", ans); } return 0; }