P4213 【模板】杜教筛(Sum)(杜教筛)

根据狄利克雷卷积的性质,可以在低于线性时间复杂度的情况下,求积性函数前缀和
#### 公式 $$ 求sum_{i=1}^{n}mu(i) $$

因为(mu*I=epsilon)

所以设(h=mu*I,S_n=sum_{i=1}^nmu(i))

[sum_{i=1}^{n}h(i)]

[=sum_{i=1}^{n}sum_{d|i}mu(lfloorfrac{i}{d} floor) imes I(d) ]

[=sum_{i=1}^nI(i)sum_{j=1}^{lfloor frac{n}{i} floor}mu(j) ]

[=sum_{i=1}^nI(i) imes S(lfloorfrac{n}{i} floor) ]

[=I(1) imes S(n)+sum_{i=2}^nI(i) imes S(lfloorfrac{n}{i} floor)]

[I(1) imes S(n)=sum_{i=1}^{n}h(i)-sum_{i=2}^{n}S(lfloorfrac{n}{i} floor) ]

[S(n)=1-sum_{i=2}^n{S(lfloorfrac{n}{i} floor)} ]

[求sum_{i=1}^nphi(i) ]

因为(phi*I=id)

所以设(h=phi*I,S_n=sum_{i=1}^nphi_i)

[sum_{i=1}^nh(i)$$$$=sum_{i=1}^nsum_{d|i}phi(lfloorfrac{i}{d} floor) imes I(d)$$$$=sum_{i=1}^nI(i) imes sum_{d|i}phi(lfloorfrac{i}{d} floor)$$$$=sum_{i=1}^nI(i) imes sum_{t=1}^{lfloorfrac{n}{i} floor}phi(t)$$]

=sum_{i=1}^nI(i) imes S(lfloorfrac{n}{i} floor)$$$$
=I(1) imes S(n)+sum_{i=2}^n I(i) imes S(lfloorfrac{n}{i} floor)

[]

S(n)=sum_{i=1}^nh(i)-sum_{i=2}^n I(i) imes S(lfloorfrac{n}{i} floor)

[]

S(n)=frac{(n+1) imes n}{2}-sum_{i=2}^n I(i) imes S(lfloorfrac{n}{i} floor)

[#### 注意事项 - 尽量减少常数 - 开头线性筛预处理的时候尽量开到$n^{frac{2}{3}}$或更大 - long long和int要区别 - 枚举2 TO N 可以整除分块 #### 代码 ```cpp #include <cstdio> #include <cstring> #include <algorithm> #include <unordered_map> using namespace std; const int MAXN = 5000000; unordered_map<int,long long> Sumphi; unordered_map<int,long long> Summu; int iprime[MAXN+5],cnt; long long mu[MAXN+5],phi[MAXN+5]; bool isprime[MAXN+5]; void prime(int n){ isprime[1]=true; mu[1]=1; phi[1]=1; for(int i=2;i<=n;i++){ if(!isprime[i]) iprime[++cnt]=i,phi[i]=i-1,mu[i]=-1; for(int j=1;j<=cnt&&iprime[j]*i<=n;j++){ isprime[iprime[j]*i]=true; mu[iprime[j]*i]=-mu[i]; phi[iprime[j]*i]=phi[i]*(iprime[j]-1); if(i%iprime[j]==0){ mu[iprime[j]*i]=0; phi[iprime[j]*i]=phi[i]*(iprime[j]); break; } } } for(int i=1;i<=n;i++){ mu[i]+=mu[i-1]; phi[i]+=phi[i-1]; } } long long djsmu(int n){//first mu second phi if(n<=MAXN) return mu[n]; if(Summu.count(n)) return Summu[n]; int mid1=0; for(int i=2,j;i<=n;i=j+1){ j=min(n/(n/i),n); mid1+=(j-i+1)*djsmu(n/i); } Summu[n]=1-mid1; return Summu[n]; } long long djsphi(int n){//first mu second phi if(n<=MAXN) return phi[n]; if(Sumphi.count(n)) return Sumphi[n]; long long mid1=0; for(int i=2,j;i<=n;i=j+1){ j=min(n/(n/i),n); mid1+=(j-i+1)*djsphi(n/i); } Sumphi[n]=1LL*(n+1)*n/2-mid1; return Sumphi[n]; } int main(){ prime(MAXN); int T,n; scanf("%d",&T); for(int i=1;i<=T;i++){ scanf("%d",&n); printf("%lld %d ",djsphi(n),djsmu(n)); } return 0; } ```]

原文地址:https://www.cnblogs.com/dreagonm/p/10077979.html