比赛
J题
gcd
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+15;
typedef long long ll;
bool vis[N];
int prime[N];
ll cnt=0;
ll n,k,t;
ll f[N], a[N], b[N];
const ll mod=1e9+7;
ll qpow(ll a,ll b)// 快速幂取模
{
ll s=1;
while(b)
{
if(b&1)
{
s=(s*a)%mod;
}
a=(a*a)%mod;
b/=2;
}
return s;
}
void Prime()// 线性筛 筛出1e4内的素数
{
int n=10000;
vis[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i])prime[++cnt]=i;
for(int j=1;j <= cnt && i*prime[j] <= n; j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
//cout<<cnt<<endl;
}
int main()
{
Prime();
for(int i = 1; i<= 1200; i++) f[i] = 1123456789123;
cin>>t;
for(int i=1;i<=t;i++) cin>>a[i];
for(int i=1;i<=t;i++) cin>>b[i];
for(int y=1;y<=t;y++)// 遍历输入的n个数据
{
n=a[y], k=b[y];
for(int i=1;i<=cnt;i++)// 对于每一个x的p次方,遍历所有素数分解
{
ll op = 0;
if(n%prime[i]==0)// 求出 n 可以分解为几个此时的素数
{
while(n%prime[i]==0)
{
n/=prime[i]; op++;
}
}
op=op*k;// 因为是n的k次方,所以 分解出k*op个
f[i]=min(f[i],op);// 求出n个数中 分解为第i个素数的最少个数
}
}
ll ans=1;
for(int i=1;i<=cnt;i++)// 所有素数最小次方的乘积就是gcd
{
ll op=qpow(prime[i],f[i]);
ans=ans*op%mod;
}
cout<<ans<<endl;
return 0;
}