bzoj1853幸运数字——容斥原理

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1853

dfs实现容斥原理即可。

注意:若在init中写“cnt++”,则出来后需要先cnt--再继续!!

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll l,r,a[100005],b[100005],ans,cnt,ct;
bool del[100005];
void init(ll x)
{
    if(x>r)return;
    a[cnt++]=x;
    init(10*x+6);
    init(10*x+8);
}
ll gcd(ll x,ll y)
{
    return x%y==0?y:gcd(y,x%y);
}
void dfs(ll x,ll y,ll z)
{
    if(x>ct)
    {
        if(y&1)ans+=r/z-(l-1)/z;
        else if(y)ans-=r/z-(l-1)/z;
        return;
    }
    dfs(x+1,y,z);
    ll tmp=z/gcd(a[x],z);
    if((double)a[x]*tmp<=r)dfs(x+1,y+1,a[x]*tmp);
}
int main()
{
    scanf("%lld%lld",&l,&r);
    init(0);
    cnt--;//!!!
    sort(a+1,a+cnt+1);
    for(ll i=1;i<=cnt;i++)
    {
        if(del[i])continue;
        for(ll j=i+1;j<=cnt;j++)
            if(a[j]%a[i]==0)del[j]=1;
        b[++ct]=a[i];
    }
    for(ll i=1;i<=ct;i++)//倒序! 
        a[i]=b[ct-i+1];
    dfs(1,0,1);
    printf("%lld",ans);
    return 0;
}

 

posted @ 2018-03-08 00:32  Zinn  阅读(160)  评论(0编辑  收藏  举报