注意审题,a是密码,那么a,2a,3a……也是密码,推出t=gcd(n,ak)的倍数也是密码。这个t,可能是a+b=c中的c,也可能是其中的a,b。如果(a,b)是密码,那么存在ax+by=c,而这个方程有解的条件是c%gcd(a,b)==0,c的因子都可以是密码。
已知t是密码,t的因子也是密码,因此我们要找最小的因子。若a是密码,b不是密码,那么gcd(a,b)的因子也不是密码。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
const long long N=1e7+10;
long long gcd(long long a,long long b){
if(b==0)return a;
return gcd(b,a%b);
}
long long n,k,a[N]={0},b[N],gcdnk,tmp,j=0;
bool fb[N];//因子bi有没有被约掉
int main(){
int bj=0;
cin>>n>>k;
for(int i=1;i<=k;i++)scanf("%lld",&a[i]);
gcdnk=gcd(n,a[k]);//
tmp=sqrt(gcdnk);
for(int i=1;i<=tmp;i++)//求gcdnk的所有因子数;
if(gcdnk%i==0)b[bj++]=i,b[bj++]=gcdnk/i;
if(b[bj-1]==b[bj-2])bj--;
sort(b,b+bj);
for(int i=1;i<k;i++)a[i]=gcd(a[i],gcdnk);
long long ans=n;
for(int i=1;i<k;i++){//找a[i] 在b[j]中是否出现过。
fb[lower_bound(b,b+bj,a[i])-b]=1;
}
for(int i=0;i<bj;i++){//去掉f[]=1的数的所有因子
if(fb[i])
for(int j=0;b[j]<b[i];j++)
if(b[i]%b[j]==0)fb[j]=1;
}
ans=1;
for(int i=0;i<bj;i++)if(!fb[i]){ans=b[i]; break;}
cout<<n/ans<<endl;
}