https://vjudge.net/contest/177343#problem/C
参考http://blog.csdn.net/sr_19930829/article/details/44938217
大概感觉容斥有两种
二进制:
e(~sf("%lld%lld",&n,&m)){
cnt=0;ans=0;
rep(i,1,m){
int x;
sf("%d",&x);if(x>0&&x<n)num[cnt++]=x;
}
int g=1<<cnt;
for(int i=1;i<g;++i){
int k=0,tmp=i;LL lcm=1;
for(int j=0;j<cnt;++j){
if(tmp&1)k++,lcm=LCM(lcm,num[j]);
tmp>>=1;
}
if(k&1)ans+=(n-1)/lcm;
else ans-=(n-1)/lcm;
}
cout<<ans<<'\n' ;
}
dfs的枚举:(貌似会快些)
LL gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
LL LCM(int x,int y){
return (LL)x/gcd(x,y)*y;
}
int cnt;
void dfs(int th,LL now,int step){
if(step>cnt)return;
LL lcm=LCM(num[th],now);
if(step&1)ans+=(n-1)/lcm;
else ans-=(n-1)/lcm;
for(int p=th+1;p<cnt;++p)
dfs(p,lcm,step+1);
}
int main(){
while(~sf("%d%d",&n,&m)){
ans=0;
cnt=0;
rep(i,1,m){
int x;
sf("%d",&x);if(x>0&&x<n)num[cnt++]=x;
}
for(int i=0;i<cnt;++i)dfs(i,num[i],1);
cout<<ans<<'\n';
}
}