SCOI2010 幸运数字

题目链接:戳我

lcm相关 容斥+搜索剪枝

选一个数的近似幸运号码,但是这样子可能有两个或多个的数的倍数相同——所以考虑容斥——我们把两个的减去。但是这样一来是三个数的lcm的数的就没有计算到,我们再加上它。。。。。。

trick1——把合法的数先预处理出来,方便之后操作。

trick2——我们从小到大判断,如果一个数已经是前面一个数的倍数了,就无需记录它了,反正它的近似幸运数字都被包含于那个数字的近似幸运数字。

trick3——如果当前的lcm到达了上届(也就是题目中的B)我们就无需再搜索了(显然吧)

trick4——从大到小暴搜,可以使得lcm更快地达到上届。

最后,我们不需要先计算出[1,r]和[1,l-1]的,然后再相减计算答案。对于一个数x,区间[A,B]内它的倍数其实就是\(\lfloor\frac{B}{x}\rfloor+\lceil\frac{A}{x}\rceil+1\)

qwqwqwq代码如下:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 100010
using namespace std;
int tot,n;
int done[MAXN];
long long A,B,ans;
long long num[MAXN],pre[MAXN];
 
inline void init(int cnt,int limit,long long val,long long base)
{
    //printf("cnt=%d limit=%d val=%lld base=%lld\n",cnt,limit,val,base);
    if(cnt>limit) {pre[++tot]=val;return;}
    init(cnt+1,limit,val+6*base,base*10);
    init(cnt+1,limit,val+8*base,base*10);
}

inline bool cmp(long long x,long long y){return x>y;}

inline long long gcd(long long x,long long y){return y==0?x:gcd(y,x%y);}

inline long long calc(long long x)
{
    long long cur_ans=0;
    cur_ans=B/x-A/x-(A%x!=0)+1;
    return cur_ans;
}

void search(int dep,int cnt,long long val) 
{
    if (val>B) return;
    if (dep>n) 
    {
        if (cnt==0) return;
        ans+=calc(val)*((cnt&1)?1:-1);
        return;
    }
    search(dep+1,cnt,val);
    long long tmp=val/gcd(val,num[dep]);
    if(1.0*tmp*num[dep]<=B)
        search(dep+1,cnt+1,tmp*num[dep]);
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    freopen("ce.out","w",stdout);
    #endif
    cin>>A>>B;
    for(int i=1;i<=10;i++) init(1,i,0,1);
    for(int i=1;i<=tot;i++)
    {
        if(!done[i]) num[++n]=pre[i];
        for(int j=i+1;j<=tot;j++)
            if(pre[j]%pre[i]==0) done[j]=1;
    }
    sort(&num[1],&num[n+1],cmp);
    search(1,0,1);
    cout<<ans<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/fengxunling/p/10432725.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值