传送门
题目大意
c [ ] c[] c[]是长度为 n n n的序列,问 l c m ( c 1 , c 2 . . . c n ) lcm(c_1,c_2...c_n)%k lcm(c1,c2...cn)是否为0,是输出 Y e s Yes Yes,不是输出 N o No No。
思路
分解质因数法求出 l c m lcm lcm,将 k k k分解质因数,只要 k k k质因数的幂次都小于等于 l c m lcm lcm中的幂次,就是 Y e s Yes Yes。
代码
bool vis[maxn];//标记非素数,0是素数
int primer[maxn/10];//存素数
int cnt=0;//记录素数个数,
void find_primer(){
for(int i=2;i <=maxn;i++){
if(!vis[i])primer[cnt++]=i;
for(int j=0;j<cnt&&primer[j]*i<=maxn;j++){
vis[i*primer[j]]=1;//筛
if(i%primer[j]==0)break;//关键!!!找到i*primer[j]的最小质因子primer[j],退出
}
}
}
map<int,int>mp;
void init(int x){
for(int i=0;primer[i]*primer[i]<=x;i++){
if(x%primer[i]==0){
int cnt1=0;
while(x%primer[i]==0){
cnt1++;
x/=primer[i];
}
mp[primer[i]]=max(mp[primer[i]],cnt1);
}
}
if(x>1)mp[x]=max(mp[x],1);
}
int main(){
scanf("%d%d",&n,&k);
find_primer();
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
init(c[i]);
}
int flag=1;
for(int i=0;primer[i]*primer[i]<=k&&i<cnt;i++){
if(k%primer[i]==0){
int cnt1=0;
while(k%primer[i]==0){
k/=primer[i];
cnt1++;
}
if(mp[primer[i]]<cnt1){
flag=0;
break;
}
}
}
if(k>1){
if(mp[k]<1){
flag=0;
}
}
if(flag){
puts("Yes");
}
else{
puts("No");
}
}