多个x^p的gcd
链接:https://ac.nowcoder.com/acm/contest/9984/J
来源:牛客网
输入描述:
第一行一个数表示 n 。
第二行 n 个数,第 i 个数表示 xi 。
第三行 n 个数,第 i 个数表示 pi 。
其中,1≤n,xi,pi≤1e4 。
输出描述:
输出一行一个数表示答案。
示例1
说明
gcd(9^1,3^2)=9
这个题就是
我们先考虑下子问题:求 , 无非就是质因数分解,然后找到大家都有的因子, 以及这个因子出现的最小次数。
举个例子: , 共同出现的质因子是 , 分别出现了 次,那么最小次数就是 , 因此
回到本题目来,该问题中多了 , 我们知道 , 那么同样地只需要在原来的子问题中找到出现了 次的质因子的最小次数,将最小次数乘以对应的 即可。
就是看看gcd(2,3,4)=gcd(2,3,2^2)就是第二个数字没有因子2,所以没有2这个贡献
#include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const ll inf=0x3f3f3f3f; const int maxn=5e6+100; const ll mod=1e9+7; struct node{ ll x; ll p; }a[maxn]; ll z[maxn]; ll x[maxn]; ll qpow(ll a,ll b){ ll ans=1; while(b){ if(b&1){ ans=(ans*a)%mod; } a=(a*a)%mod; b/=2; } return ans; } int main(){ memset(z,inf,sizeof(z)); int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i].x; } for(int i=1;i<=n;i++){ cin>>a[i].p; } for(int i=1;i<=n;i++){ ll q=a[i].x; for(int j=2;j*j<=q;j++){ ll sum=0; while(q%j==0){ sum++; q/=j; } if(sum){ x[j]++; z[j]=min(z[j],sum*a[i].p); } } if(q!=1){ z[q]=min(z[q],1ll*a[i].p); x[q]++; } } ll ans=1; for(ll i=1;i<=5e5;i++){ if(x[i]>=n&&z[i]!=4557430888798830399){ ans=(ans*qpow(i,z[i]))%mod; } } cout<<ans<<endl; }
#include<bits/stdc++.h> using namespace std; #define ll long long int n; const int N=1e4+5; int x[N],p[N],cnt; const int mod=1e9+7; const int MAX=0x3f3f3f3f; int main() { ll ans=1; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&x[i]); for(int i=1;i<=n;++i) scanf("%d",&p[i]); for(int i=2;i<=10000;++i) { cnt=MAX; for(int j=1;j<=n;++j) { int k=0; while(x[j]%i==0) { k++; x[j]=x[j]/i; } cnt=min(cnt,k*p[j]); } for(int r=1;r<=cnt;++r) ans=(ans%mod*i%mod)%mod; } printf("%lld\n",ans%mod); return 0; }