[SCOI2010]幸运数字

[SCOI2010]幸运数字

https://ac.nowcoder.com/acm/problem/20278

思路

本来以为是数位,想不出状态,后来又想着容斥一下以为都是的倍数的数量+的数量-的数量,然后就死了.万万没想到是.

思路很简单,就是先爆搜出那些合法的数/基数,其他数一定是这些数的倍数,然后把爆搜的数去个重,有些数是里面数的倍数,然后从小到大排序一下(剪枝).然后再用容斥原理统计答案即可.

坑点

题目给的是不是会爆,同时很多数据都需要开,建议都开下= - =

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll l,r,n;
vector<ll>num;
vector<ll>Num;
void DFS(ll u)
{
    if(u>r) return;
    if(u)   num.push_back(u);
    DFS(u*10+6);
    DFS(u*10+8);
}

bool cmp(ll a,ll b)
{
    return a>b;
}

void init()
{
    DFS(0ll);
    sort(num.begin(),num.end());
    int sz=num.size();
    for(int i=0;i<sz;i++)
    {
        bool flag=true;
        for(int j=0;j<i;j++)
        {
            if(num[i]%num[j]==0)    flag=false;
        }
        if(flag)    Num.push_back(num[i]);
    }
    sort(Num.begin(),Num.end(),cmp);
    n=Num.size();
}

ll Ans(ll u)
{
    return r/u-(l-1)/u;
}

ll dfs(int dep,int cnt,ll now)
{
    ll res=0;
    if(now>r)   return res;
    if(dep==n)
    {
        if(cnt==0)  return res;
        if(cnt&1)   res+=Ans(now);//+
        else        res-=Ans(now);//-
        return res;
    }
    res+=dfs(dep+1,cnt,now);
    ll sb=(now)/__gcd(now,Num[dep]);
    if(1.0*sb*Num[dep]<=r)    res+=dfs(dep+1,cnt+1,sb*Num[dep]);
    return res;
}

int main()
{
    cin>>l>>r;
    init();
    cout<<dfs(0,0,1ll)<<'\n';
    return 0;
}
lpt的小屋 文章被收录于专栏

我想要一份甜甜的爱情

全部评论
`sort(Num.begin(),Num.end(),cmp); ` 这步不加为什么会T啊
点赞 回复 分享
发布于 2021-03-22 21:07
啊?是爆搜我傻了...
点赞 回复 分享
发布于 2021-03-23 09:19

相关推荐

牛客717484937号:双飞硕没实习挺要命的
点赞 评论 收藏
分享
霁华Tel:秋招结束了,好累。我自编了一篇对话,语言别人看不懂,我觉得有某种力量在控制我的身体,我明明觉得有些东西就在眼前,但身边的人却说啥也没有,有神秘人通过电视,手机等在暗暗的给我发信号,我有时候会突然觉得身体的某一部分不属于我了。面对不同的人或场合,我表现出不一样的自己,以至于都不知道自己到底是什么样子的人。我觉得我已经做的很好,不需要其他人的建议和批评,我有些时候难以控制的兴奋,但是呼吸都让人开心。
点赞 评论 收藏
分享
3 收藏 评论
分享
牛客网
牛客企业服务