P4213 模板杜教筛
Posted ukcxrtjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4213 模板杜教筛相关的知识,希望对你有一定的参考价值。
题面:https://www.luogu.org/problem/P4213
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<queue>
#include<map>
using namespace std;
const int mod=1000000007,N=5000005;
long long phi[N];
int t,prime[N],cnt,mobius[N];
bool vis[N];
unordered_map<int,int>ans_mobius;
unordered_map<int,long long> ans_phi;
inline int read()
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
if(c=='-')
f=-1;
c=getchar();
while(c>='0'&&c<='9')
x=x*10+c-48;
c=getchar();
return x*f;
inline long long get_phi(long long x)
if(x<=N)
return phi[x];
if(ans_phi[x])
return ans_phi[x];
long long ans=((1+x)*x)/2;
for(register int l=2,r;l<=x;l=r+1)
r=x/(x/l);
ans-=(r-l+1)*get_phi(x/l);
return ans_phi[x]=ans;
inline int get_mobius(int x)
if(x<=N)
return mobius[x];
if(ans_mobius[x])
return ans_mobius[x];
int ans=1;
for(register int l=2,r;l<=x;l=r+1)
r=x/(x/l);
ans-=(r-l+1)*get_mobius(x/l);
return ans_mobius[x]=ans;
int main()
mobius[1]=phi[1]=1;
for(register int i=2;i<=N;++i)
if(!vis[i])
prime[++cnt]=i;
mobius[i]=-1;
phi[i]=i-1;
for(register int j=1;j<=cnt&&prime[j]*i<=N;++j)
vis[prime[j]*i]=1;
if(i%prime[j]==0)
phi[i*prime[j]]=phi[i]*prime[j];
break;
phi[i*prime[j]]=phi[prime[j]]*phi[i];
mobius[i*prime[j]]=-mobius[i];
for(register int i=1;i<=N;++i)
mobius[i]+=mobius[i-1];
phi[i]+=phi[i-1];
int x;
t=read();
while(t--)
x=read();
printf("%lld %d\n",get_phi(x),get_mobius(x));
return 0;
以上是关于P4213 模板杜教筛的主要内容,如果未能解决你的问题,请参考以下文章