思路很简单...加上一个一个的..再减去两两重复的..再加上三三多剪的..再减去四四多加的..直道做完...为了实现这个过程..用DFS..通过当前的是奇数个数还是偶数个数来判断当前是加还是剪..由于数据范围不大..最大也就10个数..最多需要的运算也只有10!=3628800...
值得注意的是..小心输入里的0..然后在做容斥的时候..每次不是简单的相乘..而是当前两数的最小公倍数..例如:
10 2
2
与
10 2
2 4
的结果显然是相同的...还有恶心的是..数据都用long long处理把..我就是因为这三点WA了好久...
Program:
#include<iostream>
#define ll long long
using namespace std;
ll n,m,a[12],ans,p;
ll gcd(ll a,ll b)
{
if (!b) return a;
return gcd(b,a%b);
}
void DFS(ll i,ll w,ll k)
{
for (;i<=n;i++)
if (a[i])
{
p=a[i]*w/gcd(a[i],w);
ans+=k*(m/p);
DFS(i+1,p,-k);
}
return;
}
int main()
{
ll i;
while (cin>>m>>n)
{
for (i=1;i<=n;i++) cin>>a[i];
ans=0;
m--;
DFS(1,1,1);
cout<<ans<<endl;
}
return 0;
}