min_25筛(Unfinished)
SX%N考了好几道min_25,但我还是没有学,因为听说是小概率考点,现在学也没时间了,考完再说吧。但被题解忽悠着订了今天的题,事后发现虽然他只字未提但这就是min_25板。
求 。
题解:
拆成 和 两部分算,后者只需要算 ,不在话下。
用整除分块算,由于 有 种取值,我们考虑对每一个块的 ,用 dp 求 的质数个数。
设 表示只考虑前 个质数的情况下, 中有几个“质数”。显然有:
其中 是 的质数个数,为 的, 只需枚举整除分块右端,一共 个,空间复杂度爆炸。考虑如果外层循环枚举 ,每次的 只需要枚举满足 的,可以预处理出所有右端点,则每次要取的只是一段均摊 的后缀。为什么呢?显然这样其实等价于交换循环顺序(即先枚举右端点 ,再枚举 的 ),这样显然就是 ,算出来 时大概是 4e8,实际常数较小,跑得很快。不过注意必须用前一种循环顺序,因为这样我们可以用类似滚动数组的方式转移,而不需要存两维 MLE。
复制#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=800000; ll n,ans,tot,R[N],f[N],id1[N],id2[N]; int qn,n_p,p[N]; bool v[N]; inline int gid(ll x){return x<=qn?id1[x]:id2[n/x];} int main(){ cin>>n,qn=sqrt(n); v[1]=1; for(int i=1;i<=qn;i++){ if(!v[i])p[++n_p]=i; for(int j=1;j<=n_p&&p[j]<=qn/i;j++){ v[i*p[j]]=1; if(i%p[j]==0)break; } } for(int i=1;i<=n_p;i++) for(ll j=1ll*p[i]*p[i];j<=n;j*=p[i]) ans+=n/j; for(ll l=1,r;l<=n;l=r+1){ R[++tot]=r=n/(n/l); if(r<=qn)id1[r]=tot; else id2[n/r]=tot; } for(int i=1;i<=tot;i++)f[i]=R[i]-1; for(int i=1;i<=n_p&&p[i]<=n/p[i];i++) for(int j=tot;j&&1ll*p[i]*p[i]<=R[j];j--){ f[j]-=f[gid(R[j]/p[i])]-i+1; } for(int i=1;i<=tot;i++)ans+=(f[i]-f[i-1])*(n/R[i]); cout<<ans; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App