**题意**
众所周知zhu是一个大厨,zhu一直有自己独特的咸鱼制作技巧.tang是一个咸鱼供应商,
他告诉zhu在他那里面有N条咸鱼(标号从1到N)可以被用来制作.
每条咸鱼都有一个咸鱼值Ki,初始时所有Ki都是0.
zhu是一个特别的人,他有M个咸数(咸鱼数字),对于每个咸数x,
他都会让所有满足标号是x倍数的咸鱼的咸鱼值异或上1.zhu现在想知道经过了这M个咸数的筛选之后,最终有多少条的咸鱼的咸鱼值是1?
也就是算出现奇数的个数。和之前的容斥原理有点不一样。容斥原理是
Ai+Bi+Ci-Ai*Bi-Ai*Ci-Bi*Ci+Ai*Bi*Ci
是统计出现过的次数。
写几组例子,就发现,这个题的系数不是+1,-1了。n=3时
ans=Ai+Bi+Ci-2Ai*Bi-2Ai*Ci-2Bi*Ci+4Ai*Bi*Ci
系数是
+2(k−1),−2(k−1)
,
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn = 25;
#define inf 0x3f3f3f3f
#define ll long long
int a[maxn],x[maxn],mod[maxn];
int gcd(int a,int b)
{
if(!b) return a;
else return gcd(b,a%b);
}
ll aa=1;
int n,m;
int ju(int i)
{
int ans=0,t=1;
aa=1;
while(i)
{
if(i&1) {
ans++;
if(ans==1) aa=a[t]; else aa=(ll)aa*a[t]/(ll)gcd(aa,a[t]);
if(aa>n) aa=inf;
}
if(aa==inf) break;
i=i/2;t++;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
x[1]=1;
mod[0]=1;
for(int i=2;i<=15;i++)
x[i]=-x[i-1];
for(int i=1;i<=15;i++)
mod[i]=mod[i-1]*2;
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
ll ans=0;
for(int i=1;i<(1<<m);i++)
{
int k=ju(i);
ans+=x[k]*mod[k-1]*(n/aa);
}
printf("%lld\n",ans);
}
return 0;
}