您的位置:首页 > 其它

HDU 1796 How many integers can you find (容斥原理)

2017-08-15 10:53 519 查看
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,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';
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: