每日一题 CF83D Numbers 题解

首先我们发现要记录的东西可以搞成一个最小表示法来记录
我们只需要把这个最小的k作为表示方案就可以了
然后具体的我们每次求这个答案需要递归容斥下去
首先要是能被k整除的,其次我们把小于k的方案减去即可
具体我们写个calc函数然后不断递归就可以了!
细节是我们要判断一下不是质数的情况直接return 0
我们可以先筛除小于1e6的质数,剩下的暴力判断,再加上记忆化,总复杂度O(能过)
代码:

#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr<<#x<<" = "<<x
#define sp <<"  "
#define el <<endl
#define fgx cerr<<" ------------------------------------------------ "<<endl
#define LL long long
#define DB double
#define mpt make_pair
#define pb push_back
inline int read(){
    int nm=0; bool fh=true; char cw=getchar();
    for(;!isdigit(cw);cw=getchar()) fh^=(cw=='-');
    for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
    return fh?nm:-nm;
}
#define M 1000200
#define MAXN 1000000
int pri[M],cnt; bool np[M];
unordered_map<int,int>Hv;
inline bool check(int x){
    if(x<=MAXN) return np[x]^1;
    if(Hv[x]) return Hv[x]>0;
    for(int i=2;i*i<=x;i++) if(x%i==0){
        Hv[x]=-1; return false;
    } Hv[x]=1; return true;
}
inline int gt(int x,int k){
    if(!check(k)) return 0;
    int all=x/k,R=min(k-1,x/k);
    for(int i=2;i<=R;i++) all-=gt(x/k,i);
    return all;
}

int main(){
    for(int i=2;i<=MAXN;i++){
        if(!np[i]) pri[++cnt]=i;
        for(int j=1;j<=cnt&&i*pri[j]<=MAXN;j++){
            np[i*pri[j]]=true;
            if(i%pri[j]==0) break;
        }
    }
    int l=read(),r=read(),K=read();
    printf("%d\n",gt(r,K)-gt(l-1,K));
    return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-08 11:16
点赞 评论 收藏
分享
06-20 21:22
已编辑
门头沟学院 Java
纯真的河老师在喝茶:答应了就跑啊,实习随便跑啊,别被pua了,md就是找个廉价劳动力,还平稳过度正式工,到时候跟你说没转正
点赞 评论 收藏
分享
Southyeung:我说一下我的看法(有冒犯实属抱歉):(1)简历不太美观,给我一种看都不想看的感觉,感觉字体还是排版问题;(2)numpy就一个基础包,机器学习算法是什么鬼?我感觉你把svm那些写上去都要好一点。(2)课程不要写,没人看,换成获奖经历;(3)项目太少了,至少2-3个,是在不行把网上学习的也写上去。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务