一种质数筛法
- 例题:Luogu7884
考虑 min_25 筛,可以做到
但是
考虑值域分治,使用树状数组处理
时间
考虑
取
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define fi first
#define se second
#define mkp make_pair
#define pb push_back
using namespace std;
const ll maxn=4e6+10;
ll n,g[maxn<<1],id1[maxn],id2[maxn],sq,w[maxn<<1],len,sum[maxn],cnt;
int tree[maxn*10];
bool vis[maxn*10];
ll B1,B2;
void add(ll x,ll v){
while(x<=B1){
tree[x]+=v; x+=x&-x;
}
}
ll ask(ll x){
ll v=0;
while(x){
v+=tree[x]; x-=x&-x;
} return v;
}
ll Id(ll x){
if(x<=sq) return id1[x];
return id2[n/x];
}
ll Get(ll x){
if(x<=B2) return sum[x];
if(x<=B1) return ask(x)+sum[B2];
return g[Id(x)];
}
int main(){
scanf("%lld",&n);
B1=pow(n/log2(n),0.66), B2=sqrt(n);
B1=max(B1,B2);
for(ll i=1;i<=n;i++){
ll d=n/i, r=n/d;
if(d<=B1) break;
w[++len]=d;
g[len]=d; i=r;
if(d<=sq) id1[d]=len;
else id2[n/d]=len;
i=r;
}
for(ll i=1;i<=B2;i++) sum[i]=i;
for(ll i=B2+1;i<=B1;i++) add(i,1);
for(ll i=2;i*i<=n;i++){
if(vis[i]) continue;
++cnt;
ll t=i*i; double inv=1.0/i;
for(ll j=1;j<=len&&w[j]>=t;j++)
g[j]-=Get(w[j]*inv+1e-6)-cnt;
for(ll j=B2;j>=t;j--) sum[j]-=sum[(int)(j*inv+1e-6)]-cnt;
for(ll j=i*i,o=max(B1,sq);j<=o;j+=i)
if(!vis[j]){
vis[j]=true;
if(j>B2&&j<=B1) add(j,-1);
}
}
printf("%lld",Get(n)-1);
return 0;
}
出处:https://www.cnblogs.com/Sktn0089/p/18055068
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现