Ayrat has number n, represented as it's prime factorization pi of size m, i.e. n = p1·p2·...·pm. Ayrat got secret information that that the product of all divisors of n taken modulo 109 + 7 is the password to the secret data base. Now he wants to calculate this value.
Input
The first line of the input contains a single integer m (1 ≤ m ≤ 200 000) — the number of primes in factorization of n.
The second line contains m primes numbers pi (2 ≤ pi ≤ 200 000).
Output
Print one integer — the product of all divisors of n modulo 109 + 7.
Example
2
2 3
36
3
2 3 2
1728
Note
In the first sample n = 2·3 = 6. The divisors of 6 are 1, 2, 3 and 6, their product is equal to 1·2·3·6 = 36.
In the second sample 2·3·2 = 12. The divisors of 12 are 1, 2, 3, 4, 6 and 12. 1·2·3·4·6·12 = 1728.
P是n个质数的乘积,问P的所有因子之积是多少
先把质数整理下,假设质数p[i]出现rep[i]次
P的所有因子个数应当是∏(rep[i]+1),记为S
然后对于一个质数p[i],出现0个,1个,...rep[i]个p[i]的因子个数都是S/(rep[i]+1)
因此p[i]对于答案的贡献就是j=0~rep[i]∏(p[i]^j)^(S/(rep[i]+1))
= p[i]^(rep[i]*(rep[i]+1)/2*S/(rep[i]+1))
=p[i]^(rep[i]*S/2)
此时rep[i]*S/2太大,可能爆long long,所以还要处理:
根据欧拉定理,有a^phi(p)==1(mod p),所以p[i]^(1e9+6)==1(mod 1e9+7)
所以S*rep[i]/2可以对1e9+6取模
但是1e9+6不是质数,除二不好做,所以对它的两倍2e9+12取模,防止除2之后丢失信息
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<deque> 9 #include<set> 10 #include<map> 11 #include<ctime> 12 #define LL long long 13 #define inf 0x7ffffff 14 #define pa pair<int,int> 15 #define mkp(a,b) make_pair(a,b) 16 #define pi 3.1415926535897932384626433832795028841971 17 #define mod 1000000007 18 using namespace std; 19 inline LL read() 20 { 21 LL x=0,f=1;char ch=getchar(); 22 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 23 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 24 return x*f; 25 } 26 LL n,cnt; 27 LL a[200010]; 28 LL p[200010],rep[200010]; 29 LL ans=1; 30 inline LL quickpow(LL a,LL b,LL MOD) 31 { 32 LL s=1; 33 a%=MOD; 34 b=b%(MOD-1); 35 while (b) 36 { 37 if (b&1)s=(s*a)%MOD; 38 a=(a*a)%MOD; 39 b>>=1; 40 } 41 return s; 42 } 43 int main() 44 { 45 n=read();for (int i=1;i<=n;i++)a[i]=read(); 46 sort(a+1,a+n+1); 47 for (int i=1;i<=n;i++) 48 if (i==1||a[i]!=a[i-1]) 49 { 50 p[++cnt]=a[i]; 51 rep[cnt]=1; 52 }else rep[cnt]++; 53 LL pro=1; 54 for (int i=1;i<=cnt;i++)pro=(pro*(rep[i]+1))%(2*mod-2); 55 for (int i=1;i<=cnt;i++) 56 { 57 ans=ans*quickpow(p[i],pro*rep[i]/2%(2*mod-2),mod)%mod; 58 59 } 60 printf("%lld\n",ans%mod); 61 }
也可以不把S/(rep[i]+1)和rep[i]+1约掉,搞一个{rep[i]+1}的前缀积、后缀积,就可以绕过除法把rep[i]+1挖掉
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<deque> 9 #include<set> 10 #include<map> 11 #include<ctime> 12 #define LL long long 13 #define inf 0x7ffffff 14 #define pa pair<int,int> 15 #define mkp(a,b) make_pair(a,b) 16 #define pi 3.1415926535897932384626433832795028841971 17 #define mod 1000000007 18 using namespace std; 19 inline LL read() 20 { 21 LL x=0,f=1;char ch=getchar(); 22 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 23 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 24 return x*f; 25 } 26 LL n,cnt; 27 LL a[200010]; 28 LL p[200010],rep[200010]; 29 LL s[200010],t[200010]; 30 LL phimod=500000002; 31 LL mod2=500000003; 32 LL ans=1; 33 inline LL quickpow(LL a,LL b,LL MOD) 34 { 35 LL s=1; 36 a%=MOD; 37 b=b%(MOD-1); 38 while (b) 39 { 40 if (b&1)s=(s*a)%MOD; 41 a=(a*a)%MOD; 42 b>>=1; 43 } 44 return s; 45 } 46 int main() 47 { 48 n=read();for (int i=1;i<=n;i++)a[i]=read(); 49 sort(a+1,a+n+1); 50 for (int i=1;i<=n;i++) 51 if (i==1||a[i]!=a[i-1]) 52 { 53 p[++cnt]=a[i]; 54 rep[cnt]=1; 55 }else rep[cnt]++; 56 s[0]=t[cnt+1]=1; 57 for (int i=1;i<=cnt;i++) 58 { 59 s[i]=(s[i-1]*(rep[i]+1))%(mod-1); 60 } 61 for (int i=cnt;i>=1;i--) 62 t[i]=t[i+1]*(rep[i]+1)%(mod-1); 63 for (int i=1;i<=cnt;i++) 64 { 65 LL ap=s[i-1]*t[i+1]%(mod-1); 66 ans=ans*quickpow(p[i],(rep[i]+1)*rep[i]/2%(mod-1)*ap,mod)%mod; 67 } 68 printf("%lld\n",ans%mod); 69 }