cf615D Multipliers

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

Input
2
2 3
Output
36
Input
3
2 3 2
Output
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之后丢失信息

 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 }
cf615D

也可以不把S/(rep[i]+1)和rep[i]+1约掉,搞一个{rep[i]+1}的前缀积、后缀积,就可以绕过除法把rep[i]+1挖掉

 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 }
cf615D_2

 

转载于:https://www.cnblogs.com/zhber/p/7153359.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值