杜教筛
用根号的时间求得一些特殊函数的前缀和。
要求
显然当
由于
然后具体问题具体分析,题目中希望求的是莫比乌斯函数和欧拉函数的前缀和,于是可以先线性筛出
然后就可以啦。
#include<bits/stdc++.h>
//#define feyn
#define int long long
using namespace std;
const int N=1000010;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int ff[N],gg[N],p[N/2],cnt;
bool vis[N];
inline void init(){
ff[1]=gg[1]=1;
for(int i=2;i<N;i++){
if(!vis[i])p[++cnt]=i,ff[i]=i-1,gg[i]=-1;
for(int j=1;j<=cnt&&p[j]*i<N;j++){
vis[i*p[j]]=true;
if(i%p[j]==0){
ff[i*p[j]]=ff[i]*p[j];break;
}
ff[i*p[j]]=ff[i]*(p[j]-1);
gg[i*p[j]]=gg[i]*-1;
}
}
for(int i=1;i<N;i++)ff[i]+=ff[i-1],gg[i]+=gg[i-1];
}
unordered_map<int,int>af;
inline int f(int wh){
if(wh<N)return ff[wh];
if(af[wh])return af[wh];
int ans=wh*(wh+1)/2;
for(int l=2,r;l<=wh;l=r+1){
r=wh/(wh/l);
ans-=(r-l+1)*f(wh/l);
}
return af[wh]=ans;
}
unordered_map<int,int>ag;
inline int g(int wh){
if(wh<N)return gg[wh];
if(ag[wh])return ag[wh];
int ans=1;
for(int l=2,r;l<=wh;l=r+1){
r=wh/(wh/l);
ans-=(r-l+1)*g(wh/l);
}
return ag[wh]=ans;
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
init();
int m,data;read(m);
while(m--){
read(data);
printf("%lld %lld\n",f(data),g(data));
}
return 0;
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具