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

来源:互联网 发布:软件项目管理流程图 编辑:程序博客网 时间:2024/05/29 13:37

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';    }}
阅读全文
0 0