您的位置:首页 > 其它

二进制枚举及容斥

2015-08-03 15:57 417 查看
输入n(<10^9),m(<=15) 接下来输入m个数(皆下于100)

求从1到n中不是这m个数的倍数的数的个数。

#include <iostream>

using namespace std;
typedef long long LL;

LL a[15];

LL gcd(LL a,LL b) //求a和b的最大公约数
{
if(b) return gcd(b,a%b);
return a;
}

LL lcm(LL a,LL b) //求a和b的最小公倍数
{
return a/gcd(a,b)*b;
}

int main()
{
LL n,ans,l;
int i,j,m,flag;
while(cin>>n>>m)
{
ans=0;
for(i=0;i<m;i++)
cin>>a[i];
for(i=1;i<(1<<m);i++) //利用2进制枚举出m个数的2^m-1种组合情况(减的1为都不取,即约数1的情况)
{
l=1;flag=0;
for(j=0;j<m;j++) //对i的2进制从第1位到第m位判读
{
if((1<<j)&i) //判断2进制i的第j位是否为1,即是否取了a[j]
{
l=lcm(a[j],l);
if(l>n) break;
flag++;
}
}
if(flag&1) ans+=n/l;
else ans-=n/l;
}
cout<<n-ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: