题目链接:点击这里
题目大意:
给定一个正整数
n
n
n ,求其所有约数的乘积,即求
∏
d
∣
n
d
m
o
d
1
e
9
+
7
\prod\limits_{d|n}d \mod 1e9+7
d∣n∏dmod1e9+7
题目分析:
将
n
n
n 用唯一分解定理展开
n
=
∏
i
=
1
x
p
i
a
i
n=\prod_{i=1}^xp_i^{a_i}
n=∏i=1xpiai ,逐个质数考虑贡献:
对于
p
i
a
i
p_i^{a_i}
piai 来说,自己有
1
+
2
+
.
.
.
+
a
i
=
a
i
⋅
(
a
i
+
1
)
2
1+2+...+a_i=\frac{a_i·(a_i+1)}{2}
1+2+...+ai=2ai⋅(ai+1) 种选法,对于剩余部分有
∏
j
=
1
x
(
a
j
+
1
)
a
i
+
1
\frac{\prod_{j=1}^{x}(a_{j}+1)}{a_i+1}
ai+1∏j=1x(aj+1) 种选法,所以该质数的贡献为
p
i
a
i
⋅
(
a
i
+
1
)
2
⋅
∏
j
=
1
x
(
a
j
+
1
)
a
i
+
1
=
p
i
∏
j
=
1
x
(
a
j
+
1
)
⋅
a
i
2
p_i^{\frac{a_i·(a_i+1)}{2}·\frac{\prod_{j=1}^{x}(a_{j}+1)}{a_i+1}}=p_i^{\frac{\prod_{j=1}^{x}(a_{j}+1)·a_i}{2}}
pi2ai⋅(ai+1)⋅ai+1∏j=1x(aj+1)=pi2∏j=1x(aj+1)⋅ai
由于指数很大需要用扩展欧拉定理降幂
a
b
≡
a
b
%
φ
(
p
)
+
φ
(
p
)
m
o
d
p
a^b\equiv a^{b\%\varphi(p)+\varphi(p)} \mod p
ab≡ab%φ(p)+φ(p)modp
因为指数要除以
2
2
2 的所以我们可以在计算
∏
j
=
1
x
(
a
j
+
1
)
⋅
a
i
\prod_{j=1}^{x}(a_{j}+1)·a_i
∏j=1x(aj+1)⋅ai 的时候先模
2
φ
(
p
)
2\varphi(p)
2φ(p) 以保证降幂的正确性
然后用快速幂把所有贡献乘起来即可
具体细节见代码:
// Problem: D - Multipliers
// Contest: Virtual Judge - 康复训练02
// URL: https://vjudge.net/contest/485549#problem/D
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<unordered_map>
#define ll long long
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
#define int ll
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
using namespace std;
int read()
{
int res = 0,flag = 1;
char ch = getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
{
res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
ch = getchar();
}
return res*flag;
}
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,mul,res;
map<int,int>mp;
int qpow(int a,int b)
{
int res = 1;
while(b)
{
if(b&1) res = 1LL*a*res%mod;
a = 1LL*a*a%mod;
b >>= 1;
}
return res;
}
signed main()
{
n = read();
for(int i = 1;i <= n;i++)
{
int x = read();
mp[x]++;
}
int sum = 1,res = 1;
for(auto it:mp) sum = sum*(it.second+1)%(2*(mod-1));
// cout<<sum<<endl;
for(auto it:mp)
{
int val = it.first,cnt = it.second;
res = res*qpow(val,sum*cnt/2%(mod-1)+mod-1)%mod;
}
cout<<res<<endl;
return 0;
}