先是一道有关费马小定理的题。
费马小定理内容:假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p),即:假如a是整数,p是质数,且a,p互质,那么a的(p-1)次方模p的余数恒等于1。
题目:Codeforces Round #338(Div. 2) D. Multipliers
题意很简明,给你一个数的所有质因数,然后让你求出这个数所有因数的乘积。
对于每个质因子,对答案的贡献为p^(d[p] *(d[p]-1) \ 2 * d[s])
d[p]表示p的因子数量,d[s]表示s这个数的因子数量
数量可以由因子数量定理求得,d[s] =(a1+1)(a2+1)...(an+1),a1.a2.a3表示s的质因子的次数。
但是由于指数可能很大,所以我们就需要使用费马小定理就好了
但是又有除2的操作,mod-1有不是质数,不存在逆元,所以先对2(mod-1)取模。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
long long mod = 1e9+7;
long long mod2 = 2LL*(mod - 1);
long long quickpow(long long a,long longb,long long c)
{
long long ans = 1;
while(b)
{
if(b&1)ans = ans * a % c;
a = a * a % c;
b>>=1;
}
return ans;
}
int cnt[maxn];
int p[maxn];
int vis[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&p[i]);
cnt[p[i]]++;//记录每个数的个数
}
long long tot = 1;
for(int i=1;i<=n;i++)
{
if(vis[p[i]])continue;//跳出此次循环
vis[p[i]]=1;
tot = tot*(cnt[p[i]]+1)%mod2;//求因子数= (a1+1)(a2+1)...(an+1),a1.a2.a3表示质因子的次数
}
memset(vis,0,sizeof(vis));
long long ans = 1;
for(int i=1;i<=n;i++)
{
if(vis[p[i]])continue;
vis[p[i]]=1;
ans=ans*quickpow(p[i],(tot*cnt[p[i]]/2)%mod2,mod)%mod;//每个数的贡献,费马小定理
}
cout<<ans<<endl;
}
家人在医院住院,需要去医院陪床,所以就写这些吧。
以上