【题目】
【代码】
直接粘贴同学大佬的博客吧
#include<cstdio>
#include<cstring>
#include<algorithm>
#define M 505
#define N 100005
#define S 1<<15
using namespace std;
pair<int,int>p[N];
long long n,f[S];
int m,t,k,sum,temp;
int a[M],prime[N],factor[N];
bool used[N],mark[N];
void prime_shaker()
{
int i,j;
memset(mark,true,sizeof(mark));
mark[0]=mark[1]=false;
for(i=2;i<N;++i)
{
if(mark[i]) prime[++sum]=i;
for(j=1;j<=sum&&i*prime[j]<N;++j)
{
mark[i*prime[j]]=false;
if(i%prime[j]==0) break;
}
}
}
void divide(int x)
{
int i;
temp=0;
for(i=1;i<=sum&&1ll*prime[i]*prime[i]<=x;++i)
{
if(x%prime[i]) continue;
p[++temp]=make_pair(prime[i],0);
while(x%prime[i]==0) x/=prime[i],p[temp].second++;
if(!used[prime[i]]) used[prime[i]]=true,factor[++t]=prime[i];
}
if(x>1) p[++temp]=make_pair(x,1),factor[++t]=x;
}
bool check(int x)
{
int i,j;
if(n%x)
return false;
divide(x);
for(i=1;i<=temp;++i)
{
long long mul=1;
for(j=1;j<=p[i].second;++j)
mul*=p[i].first;
if((n/mul)%p[i].first==0) return false;
}
return true;
}
bool c()
{
int i;
long long nn=n;
for(i=1;i<=k;++i)
while(nn%factor[i]==0)
nn/=factor[i];
if(nn>1)
return true;
return false;
}
int calc(int x)
{
int i,ans=0;
for(i=1;i<=k;++i)
if(x%factor[i]==0)
ans|=(1<<(i-1));
return ans;
}
int main()
{
// freopen("division.in","r",stdin);
// freopen("division.out","w",stdout);
int x,i,j;
int num=0,flag=1;
prime_shaker();
scanf("%lld%d",&n,&m);
for(i=1;i<=m;++i)
{
scanf("%d",&x);
if(x==1) {flag=2;continue;}
if(check(x)) a[++num]=x;
}
sort(factor+1,factor+t+1);
for(i=1;i<=t;++i)
if(factor[i]!=factor[i-1])
factor[++k]=factor[i];
if(c()) {printf("0");return 0;}
for(i=1;i<=num;++i)
a[i]=calc(a[i]);
f[0]=1;
for(i=0;i<(1<<k);++i)
for(j=1;j<=num;++j)
if((i&a[j])==0&&i<a[j])
f[i|a[j]]+=f[i];
printf("%lld",f[(1<<k)-1]*flag);
// fclose(stdin);
// fclose(stdout);
return 0;
}