思路很简单啊,为了好计算,考虑每个素因子出现的次数,然后很容易想到递推方法。
这个题目:
1 , pow_mod(a , b , mod) 当mod是素数时且b远大于mod 那么 pow_mod(a, b,mod ) = pow_mod(a , b%(mod-1),mod);
2 , 求1 ->x 的和不能直接x*(x+1)/2 % mod ; 因为有除法啊。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N = 1e5 + 100;
const ll lim = 1e18 + 10;
#define rep1(i,x,y) for(int i=x;i<=(int)y;i++)
#define rep(i,n) for(int i=0;i<(int)n;i++)
const ll mod = 1e9 + 7;
const ll mod2 = 1e9 + 6;
ll pow_mod(int a,ll b){
ll ans = 1 , te = a;
while(b > 0){
if(b & 1) ans=ans*te%mod;
b>>=1;
te=te*te%mod;
}
return ans;
}
bool vis[N]={0};
vector<int> pri;
int n,a[N],K,po[N];
void init(){
int m = (sqrt(N));
for(int i=2;i<=m;i++) if(!vis[i])
for(int j=i*i;j<N;j+=i) vis[j]=1;
for(int i=2;i<N;i++) if(!vis[i]) {
pri.push_back(i);
po[i] = pri.size()-1;
}
K = pri.size();
}
ll cnt[N];
void get(int i,int x){
int m=sqrt(x + 0.5);
for(auto v : pri){
if(v > m || x == 1) break;
while(x % v ==0){
x/=v; cnt[po[v]]+=i;
}
}
if(x > 1) cnt[po[x]]+=i;
}
int mul(ll x) {
ll a = x;
ll b = x + 1;
if(a & 1) b /= 2;
else a /= 2;
a %= mod2;
b %= mod2;
return a * b % mod2;
}
ll le[N],ri[N];
int main()
{
init();
while(scanf("%d",&n)==1){
rep(i,K) cnt[i] = 0;
rep1(i,1,n){
scanf("%d",&a[i]); get(a[i],i);
}
ll ans = 1;
le[0] = ri[K-1] = 1;
rep1(i,1,K-1) le[i] = le[i-1]*(cnt[i-1]+1)%mod2;
for(int i=K-2;i>=0;i--) ri[i] = ri[i+1]*(cnt[i+1]+1)%mod2;
rep(i,K){
ll ji = pow_mod(pri[i],(ll)(le[i]*ri[i]%mod2)*mul(cnt[i])%mod2);
ans = ans*ji%mod;
}
cout<<ans<<endl;
}
return 0;
}