应用:求 |AUBUC|-->集合A,B,C中不重复元素的总个数。
S={1,2,3......600} 求其中被2,3,5除尽的数的数目。
另A,B,C分别表示S中被2,3,5除尽的数。
|A|=600/2=300 , |B|=600/3=200 |C|=600/5=120
|A交B|=600/(2*3)=100 |A交C|=600/(2*5)=60 |B交C|=600/(3*5)=40
|A交B交C|=600/(2*3*5)=20
|A交B交C|=|A|+|B|+|C|-(|A交B|+|A交C|+ |B交C|)+|A交B交C|=440
HDU——1796
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#define maxn 125
__int64 x,n,ans;
int cnt,m;
__int64 num[maxn];
__int64 gcd(__int64 a,__int64 b)
{
return b==0?a:(gcd(b,a%b));
}
void dfs(int id,bool flag,__int64 lcm)//id表示起始位置,flag表示加还是减,累加最小公倍数
{
lcm=lcm*num[id]/(gcd(lcm,num[id]));
if(flag)
ans+=n/lcm;
else
ans-=n/lcm;
for(int i=id+1;i<cnt;i++)
{
dfs(i,!flag,lcm);
}
}
int main()
{
while(scanf("%I64d%d",&n,&m)!=EOF)
{
memset(num,0,sizeof(num));
cnt=0;
for(int i=0;i<m;i++)
{
scanf("%I64d",&x);
if(x!=0)
num[cnt++]=x;
}
ans=0;
n--;
for(int i=0;i<cnt;i++)
{
dfs(i,true,num[i]);
}
printf("%I64d\n",ans);
}
return 0;
}