lightoj 1276 Very Lucky Numbers

题目大意 : lucky number是指只含4和7的数字。very lucky number是指lucky number 和能有several个lucky number做乘积得到的数。询问一些区间[A,B](A,B<=1e12)之间very lucky number 的数量。

思路: 预先处理出所有的8000+个lucky number ,然后对这些数dfs得到范围内的所有very lucky number 。然后对于每个区间二分即可。


lucky number 只有2^12=4096个。

然后dfs。碰到乘起来超过范围的直接结束搜索。


接着利用超级屌的二分搞定。。


vector<ll> T;
void dfs(int d,ll dig) {
    if(d>12)return;
    T.pb(dig);
    dfs(d+1,dig*10+4);
    dfs(d+1,dig*10+7);
}
int tmp;
void dfs2(ll dig,int t) {
    if(dig!=1)T.pb(dig);
    for(int i=t; i<tmp; i++) {
        if(T[i]<=1000000000000LL/dig)dfs2(dig*T[i],i);
        else break;
    }
}
int lower(ll x) {
    if(x<T[0])return 0;
    if(x>=T[T.size()-1])return T.size();
    int l=0,r=T.size()-1;
    int mid;
    while(l<=r) {
        mid=(l+r)>>1;
        if(T[mid]==x)return mid+1;
        if(x>T[mid])l=mid+1;
        else r=mid-1;
    }
    return min(r,mid)+1;
}
int main() {
    T.clear();
    dfs(1,4);
    dfs(1,7);
    tmp=T.size();
    sort(T.begin(),T.end());
    dfs2(1,0);
    sort(T.begin(),T.end());
    T.erase(unique(T.begin(),T.end()),T.end());
    int TT;
    scanf("%d",&TT);
    for(int tt=1; tt<=TT; tt++) {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        printf("Case %d: %d\n",tt,lower(b)-lower(a-1));
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值