数论函数相关

一.数论函数的定义与一些基本的数论函数.

数论函数:数论函数定义为定义域为正整数且陪域为复数的函数.

积性函数:若有数论函数 f f f满足 gcd ⁡ ( n , m ) = 1 \gcd(n,m)=1 gcd(n,m)=1 f ( n m ) = f ( n ) f ( m ) f(nm)=f(n)f(m) f(nm)=f(n)f(m),则函数 f f f被称为积性函数.

完全积性函数:若有数论函数 f f f满足任何时候 f ( n m ) = f ( n ) f ( m ) f(nm)=f(n)f(m) f(nm)=f(n)f(m),则函数 f f f被称为完全积性函数.

接下来我们定义几个基本的数论函数.

元函数 e ( n ) = [ n = 1 ] e(n)=[n=1] e(n)=[n=1].

恒等函数 I ( n ) = 1 I(n)=1 I(n)=1.

单位函数 ε ( n ) = n \varepsilon(n)=n ε(n)=n.

约数个数函数 τ ( n ) = ∑ d ∣ n 1 \tau(n)=\sum_{d|n}1 τ(n)=dn1.

约数和函数 σ ( n ) = ∑ d ∣ n d \sigma(n)=\sum_{d|n}d σ(n)=dnd.

约数函数性质参见整除理论与线性丢番图方程相关.

欧拉函数 ϕ ( n ) = ∑ i = 1 n [ gcd ⁡ ( i , n ) = 1 ] \phi(n)=\sum_{i=1}^{n}[\gcd(i,n)=1] ϕ(n)=i=1n[gcd(i,n)=1].

欧拉函数性质参见欧拉函数相关.


二.Dirichlet卷积及其计算.

Dirichlet卷积:定义两个数论函数 f , g f,g f,g的Dirichlet卷积 f × g f\times g f×g为:
( f × g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f\times g)(n)=\sum_{d|n}f(d)g\left(\frac{n}{d}\right) (f×g)(n)=dnf(d)g(dn)

考虑如何计算两个数论函数的Dirichlet卷积,可以按照定义算,那样是 O ( n n ) O(n\sqrt{n}) O(nn )的.

还有一种 O ( n log ⁡ n ) O(n\log n) O(nlogn)的计算方法是,将枚举因数改为枚举倍数,计算总贡献.

代码如下:

void Dir_mul(int *a,int *b,int n){
  for (int i=n;i>=1;--i){
    for (int j=2;i*j<=n;++j) a[i*j]+=a[i]*b[j];
    a[i]*=b[1];
  }
}



三.Dirichlet卷积的相关性质.

Dirichlet卷积的性质1:所有数论函数的Dirichlet卷积满足交换律,即:
f × g = g × f f\times g=g\times f f×g=g×f

证明:
( f × g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) = ( g × f ) ( n ) (f\times g)(n)=\sum_{d|n}f(d)g\left(\frac{n}{d}\right)=(g\times f)(n) (f×g)(n)=dnf(d)g(dn)=(g×f)(n)

证毕.

Dirichlet卷积的性质2:所有数论函数的Dirichlet卷积满足结合律,即:
f × g × h = f × ( g × h ) f\times g\times h=f\times (g\times h) f×g×h=f×(g×h)

证明:
( f × g × h ) ( n ) = ∑ t d 3 = n ( ∑ d 1 d 2 = t f ( d 1 ) g ( d 2 ) ) h ( d 3 ) = ∑ d 1 d 2 d 3 = n f ( d 1 ) g ( d 2 ) h ( d 3 ) = ∑ d 1 t = n f ( d 1 ) ∑ d 2 d 3 = t g ( d 2 ) h ( d 3 ) = ( f × ( g × h ) ) ( n ) (f\times g\times h)(n)\\ =\sum_{td_3=n}\left(\sum_{d_1d_2=t}f(d_1)g(d_2)\right)h(d_3)\\ =\sum_{d_1d_2d_3=n}f(d_1)g(d_2)h(d_3)\\ =\sum_{d_1t=n}f(d_1)\sum_{d_2d_3=t}g(d_2)h(d_3)\\ =(f\times (g\times h))(n) (f×g×h)(n)=td3=n(d1d2=tf(d1)g(d2))h(d3)=d1d2d3=nf(d1)g(d2)h(d3)=d1t=nf(d1)d2d3=tg(d2)h(d3)=(f×(g×h))(n)

证毕.

Dirichlet卷积的性质3:所有数论函数的Dirichlet卷积关于加法满足分配律,即:
( f + g ) × h = f × h + g × h (f+g)\times h=f\times h+g\times h (f+g)×h=f×h+g×h

证明:
( ( f + g ) × h ) ( n ) = ∑ d ∣ n ( f ( d ) + g ( d ) ) h ( n d ) = ∑ d ∣ n f ( d ) h ( n d ) + ∑ d ∣ n g ( d ) h ( n d ) = ( f × h ) ( n ) + ( g × h ) ( n ) ((f+g)\times h)(n)\\ =\sum_{d|n}(f(d)+g(d))h\left(\frac{n}{d}\right)\\ =\sum_{d|n}f(d)h\left(\frac{n}{d}\right)+\sum_{d|n}g(d)h\left(\frac{n}{d}\right)\\ =(f\times h)(n)+(g\times h)(n) ((f+g)×h)(n)=dn(f(d)+g(d))h(dn)=dnf(d)h(dn)+dng(d)h(dn)=(f×h)(n)+(g×h)(n)

证毕.

Dirichlet卷积的性质4:两个积性函数的Dirichlet卷积仍然是积性函数.

证明:
若在 gcd ⁡ ( n , m ) = 1 \gcd(n,m)=1 gcd(n,m)=1时,有 f ( n m ) = f ( n ) f ( m ) , g ( n m ) = g ( n ) g ( m ) f(nm)=f(n)f(m),g(nm)=g(n)g(m) f(nm)=f(n)f(m),g(nm)=g(n)g(m),则:
( f × g ) ( n ) ( f × g ) ( m ) = ( ∑ d ∣ n f ( d ) g ( n d ) ) ( ∑ d ∣ m f ( d ) g ( m d ) ) = ∑ d 1 ∣ n ∑ d 2 ∣ m f ( d 1 ) g ( n d 1 ) f ( d 2 ) g ( m d 2 ) = ∑ d 1 ∣ n ∑ d 2 ∣ m f ( d 1 d 2 ) g ( n m d 1 d 2 ) = ∑ d ∣ n m f ( d ) g ( n m d ) = ( f × g ) ( n m ) (f\times g)(n)(f\times g)(m)\\ =\left(\sum_{d|n}f(d)g\left(\frac{n}{d}\right)\right)\left(\sum_{d|m}f(d)g\left(\frac{m}{d}\right)\right)\\ =\sum_{d_1|n}\sum_{d_2|m}f(d_1)g\left(\frac{n}{d_1}\right)f(d_2)g\left(\frac{m}{d_2}\right)\\ =\sum_{d_1|n}\sum_{d_2|m}f(d_1d_2)g\left(\frac{nm}{d_1d_2}\right)\\ =\sum_{d|nm}f(d)g\left(\frac{nm}{d}\right)\\ =(f\times g)(nm) (f×g)(n)(f×g)(m)=dnf(d)g(dn)dmf(d)g(dm)=d1nd2mf(d1)g(d1n)f(d2)g(d2m)=d1nd2mf(d1d2)g(d1d2nm)=dnmf(d)g(dnm)=(f×g)(nm)

证毕.


三.Dirichlet卷积逆.

如何求一个数论函数的在Dirichlet卷积意义下的逆呢?

首先我们需要知道,Dirichlet卷积的单位元为元函数 e e e.

首先对于一个已知的数论函数 f f f,它的Dirichlet卷积逆 f − 1 f^{-1} f1必然得满足:
f ( 1 ) f − 1 ( 1 ) = 1 ⇒ f − 1 ( 1 ) = 1 f ( 1 ) f(1)f^{-1}(1)=1\Rightarrow f^{-1}(1)=\frac{1}{f(1)} f(1)f1(1)=1f1(1)=f(1)1

然后,我们考虑 n > 1 n>1 n>1时构造 f − 1 ( n ) f^{-1}(n) f1(n)
∑ d ∣ n f − 1 ( d ) f ( n d ) = 0 f − 1 ( n ) f ( 1 ) + ∑ d ∣ n ∧ d < n f − 1 ( d ) f ( n d ) = 0 f − 1 ( n ) = − 1 f ( 1 ) ∑ d ∣ n ∧ d < n f − 1 ( d ) f ( n d ) \sum_{d|n}f^{-1}(d)f\left(\frac{n}{d}\right)=0\\ f^{-1}(n)f(1)+\sum_{d|n\wedge d<n}f^{-1}(d)f\left(\frac{n}{d}\right)=0\\ f^{-1}(n)=-\frac{1}{f(1)}\sum_{d|n\wedge d<n}f^{-1}(d)f\left(\frac{n}{d}\right) dnf1(d)f(dn)=0f1(n)f(1)+dnd<nf1(d)f(dn)=0f1(n)=f(1)1dnd<nf1(d)f(dn)

所以我们有:
f − 1 ( n ) = { 1 f ( 1 ) n = 1 − 1 f ( 1 ) ∑ d ∣ n ∧ d < n f − 1 ( d ) f ( n d ) n > 1 f^{-1}(n)= \left\{\begin{matrix} \frac{1}{f(1)}&n=1\\ -\frac{1}{f(1)}\sum_{d|n\wedge d<n}f^{-1}(d)f\left(\frac{n}{d}\right)&n>1 \end{matrix}\right. f1(n)={f(1)1f(1)1dnd<nf1(d)f(dn)n=1n>1

同时我们知道了,一个数论函数 f f f存在Dirichlet卷积逆当且仅当 f ( 1 ) ≠ 0 f(1)\neq 0 f(1)=0.


四.Mobius函数.

Mobius函数:我们把恒等函数 I I I的Dirichlet卷积逆称为Mobius函数,记为 μ \mu μ.

现在我们来求一下 μ ( n ) \mu(n) μ(n)的具体数值.

首先,根据上面得出的结论,我们可以构造 μ \mu μ函数为:
μ ( n ) = { 1 n = 1 − ∑ d ∣ n ∧ d < n μ ( d ) n > 1 \mu(n)= \left\{\begin{matrix} 1&n=1\\ -\sum_{d|n\wedge d<n}\mu(d)&n>1 \end{matrix}\right. μ(n)={1dnd<nμ(d)n=1n>1

尝试打出一个表:
1 2 3 4 5 6 7 8 9 ⋯ 1 − 1 − 1 0 − 1 1 − 1 0 0 ⋯ \begin{matrix} 1&2&3&4&5&6&7&8&9&\cdots\\ 1&-1&-1&0&-1&1&-1&0&0&\cdots \end{matrix} 112131405161718090

设唯一分解 n = ∏ i = 1 k p i c i n=\prod_{i=1}^{k}p_i^{c_i} n=i=1kpici,我们发现 μ \mu μ函数可能满足这么一个表达式:
μ ( n ) = { ( − 1 ) k ∀ i , c i = 1 0 ∃ i , c i > 1 \mu(n)= \left\{\begin{matrix} (-1)^{k}&\forall i,c_i=1\\ 0&\exists i,c_i>1 \end{matrix}\right. μ(n)={(1)k0i,ci=1i,ci>1

证明:
首先当 n = 1 n=1 n=1时,显然有 μ ( 1 ) I ( 1 ) = e ( 1 ) \mu(1)I(1)=e(1) μ(1)I(1)=e(1).
n > 1 n>1 n>1,设唯一分解 n = ∏ i = 1 k p i c i n=\prod_{i=1}^{k}p_i^{c_i} n=i=1kpici,令 m = ∏ i = 1 k p i m=\prod_{i=1}^{k}p_i m=i=1kpi,则有:
∑ d ∣ n μ ( d ) = ∑ d ∣ m μ ( d ) \sum_{d|n}\mu(d)=\sum_{d|m}\mu(d) dnμ(d)=dmμ(d)

此时仍然有 m > 1 m>1 m>1,设 t = ∏ i = 1 k − 1 p i c i t=\prod_{i=1}^{k-1}p_i^{c_i} t=i=1k1pici,则有:
∑ d ∣ m μ ( d ) = ∑ d ∣ t ( μ ( d ) + μ ( d p k ) ) \sum_{d|m}\mu(d)=\sum_{d|t}(\mu(d)+\mu(dp_{k})) dmμ(d)=dt(μ(d)+μ(dpk))

由于 μ ( d ) \mu(d) μ(d) μ ( d p k ) \mu(dp_{k}) μ(dpk)必定为相反数,所以 μ ( d ) + μ ( d p k ) = 0 \mu(d)+\mu(dp_{k})=0 μ(d)+μ(dpk)=0,即:
∑ d ∣ n μ ( d ) = ∑ d ∣ t 0 = 0 \sum_{d|n}\mu(d)=\sum_{d|t}0=0 dnμ(d)=dt0=0

证毕.

现在我们得到了 μ \mu μ函数的一个通项公式.


五.Mobius函数的求解.

求解单个Mobius函数的方法非常简单,可以通过直接分解质因数做到 O ( n ) O(\sqrt{n}) O(n )求解.

代码入下:

int Get_mu(int n){
  int res=1,now=n;
  for (int i=2;i*i<=n;++i)
    if (now%i==0){
      if ((now/=i)%i==0) return 0;
      res=-res;
    }
  return now>1?-res:res;
}

而显然,Mobius函数也非常容易用线性筛筛出.

时间复杂度 O ( n ) O(n) O(n).

代码如下:

int b[N+9],pr[N+9],cp;
int mu[N+9];

void Sieve(){
  mu[1]=1;
  for (int i=2;i<=n;++i){
  	if (!b[i]) pr[++cp]=i,mu[i]=-1;
  	for (int j=1;j<=cp&&i*pr[j]<=n;++j){
  	  b[i*pr[j]]=1;
  	  if (i%pr[j]==0) {mu[i*pr[j]]=0;break;}
  	  mu[i*pr[j]]=-mu[i];
  	}
  }
}



六.Mobius反演及其应用.

根据 I × μ = e I\times \mu=e I×μ=e,我们还可以推出一个反演:
f = I × g ⇔ g = μ × f f=I\times g\Leftrightarrow g=\mu\times f f=I×gg=μ×f

将上述反演形式写成和式,我们就可以得到Mobius反演
f ( n ) = ∑ d ∣ n g ( d ) ⇔ g ( n ) = ∑ d ∣ n f ( d ) μ ( n d ) f(n)=\sum_{d|n}g(d)\Leftrightarrow g(n)=\sum_{d|n}f(d)\mu\left(\frac{n}{d}\right) f(n)=dng(d)g(n)=dnf(d)μ(dn)

Mobius反演的一个经典作用是和式变换,例如:
∑ i = 1 n ∑ j = 1 m [ gcd ⁡ ( i , j ) = 1 ] = ∑ i = 1 n ∑ j = 1 m ∑ d ∣ gcd ⁡ ( i , j ) μ ( d ) = ∑ i = 1 n ∑ j = 1 m ∑ d ∣ i ∧ d ∣ j μ ( d ) = ∑ d = 1 min ⁡ ( n , m ) μ ( d ) ∑ i = 1 ⌊ n d ⌋ ∑ i = 1 ⌊ m d ⌋ 1 = ∑ d = 1 min ⁡ ( n , m ) μ ( d ) ⌊ n d ⌋ ⌊ m d ⌋ \sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)=1]\\ =\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|\gcd(i,j)}\mu(d)\\ =\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|i\wedge d|j}\mu(d)\\ =\sum_{d=1}^{\min(n,m)}\mu(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{i=1}^{\left\lfloor\frac{m}{d}\right\rfloor}1\\ =\sum_{d=1}^{\min(n,m)}\mu(d)\left\lfloor\frac{n}{d}\right\rfloor \left\lfloor\frac{m}{d}\right\rfloor i=1nj=1m[gcd(i,j)=1]=i=1nj=1mdgcd(i,j)μ(d)=i=1nj=1mdidjμ(d)=d=1min(n,m)μ(d)i=1dni=1dm1=d=1min(n,m)μ(d)dndm

然后通过经典的除法分块,我们可以做到 O ( n + m ) O(\sqrt{n}+\sqrt{m}) O(n +m )求解这个式子.


七.一些特殊的Dirichlet卷积.

卷积1 f × e = f f\times e=f f×e=f.

这就是元函数的作用…

卷积2 e = μ × I e=\mu\times I e=μ×I.

卷积3 ε = ϕ × I \varepsilon=\phi\times I ε=ϕ×I.

证明:
首先我们构造函数 f = ϕ × I f=\phi\times I f=ϕ×I,由于 ϕ \phi ϕ I I I都是积性函数,所以 f f f也是积性函数.
此时我们可以把 n n n写成唯一分解形式 n = ∏ i = 1 k p i c i n=\prod_{i=1}^{k}p_i^{c_i} n=i=1kpici,容易发现现在只需要证明:
∑ d ∣ p i c i ϕ ( d ) = p i c i \sum_{d|p_i^{c_i}}\phi(d)=p_i^{c_i} dpiciϕ(d)=pici

于是有:
∑ d ∣ p i c i ϕ ( d ) = ∑ j = 0 c i ϕ ( p i j ) = 1 + ∑ j = 0 c i − 1 ( p i − 1 ) p i j = 1 + ( p i − 1 ) 1 − p i c i 1 − p i = 1 + p i c i − 1 = p i c i \sum_{d|p_i^{c_i}}\phi(d)=\sum_{j=0}^{c_i}\phi(p_i^{j})\\ =1+\sum_{j=0}^{c_i-1}(p_i-1)p_i^{j}\\ =1+(p_i-1)\frac{1-p_i^{c_i}}{1-p_i}\\ =1+p_i^{c_i}-1\\ =p_i^{c_i} dpiciϕ(d)=j=0ciϕ(pij)=1+j=0ci1(pi1)pij=1+(pi1)1pi1pici=1+pici1=pici

证毕.

卷积4 ϕ = μ × ε \phi=\mu\times \varepsilon ϕ=μ×ε.

证明:
考虑用容斥计算欧拉函数,设唯一分解 n = ∏ i = 1 k p i c i n=\prod_{i=1}^{k}p_i^{c_i} n=i=1kpici,我们可以得到:
ϕ ( n ) = ∑ T ⊆ [ k ] ( − 1 ) ∣ T ∣ n ∏ i ∈ T p i \phi(n)=\sum_{T\subseteq [k]}(-1)^{|T|}\frac{n}{\prod_{i\in T}p_i}\\ ϕ(n)=T[k](1)TiTpin

m = ∏ i = 1 k p i m=\prod_{i=1}^{k}p_i m=i=1kpi,有:
ϕ ( n ) = ∑ d ∣ m μ ( d ) n d \phi(n)=\sum_{d|m}\mu(d)\frac{n}{d}\\ ϕ(n)=dmμ(d)dn

对于满足 d ∣ n d|n dn却不满足 d ∣ m d|m dm d d d必然有 μ ( d ) = 0 \mu(d)=0 μ(d)=0,所以:
ϕ ( n ) = ∑ d ∣ n μ ( d ) n d \phi(n)=\sum_{d|n}\mu(d)\frac{n}{d} ϕ(n)=dnμ(d)dn

证毕.


八.杜教筛.

假设有一个数论函数 f ( n ) f(n) f(n),考虑计算下式:
∑ i = 1 n f ( n ) \sum_{i=1}^{n}f(n) i=1nf(n)

看起来除了一些非常简单的数论函数(例如 e , I , ε e,I,\varepsilon e,I,ε),怎么着我们也得用 O ( n ) O(n) O(n)的是时间复杂度来求出(例如 μ , ϕ \mu,\phi μ,ϕ).

但如果 f ( n ) f(n) f(n)有一些特殊的性质的话,我们也可以用低于 O ( n ) O(n) O(n)的时间复杂度求出!这也是接下来研究的重点.

我们先构造出两个数论函数 h , g h,g h,g满足 h = g × f h=g\times f h=g×f,且 h , g h,g h,g都非常好算.

那么我们有:
∑ i = 1 n h ( i ) = ∑ i = 1 n ∑ d ∣ i g ( d ) f ( i d ) = ∑ d = 1 n g ( d ) ∑ i = 1 ⌊ n d ⌋ f ( i ) \sum_{i=1}^{n}h(i)=\sum_{i=1}^{n}\sum_{d|i}g(d)f\left(\frac{i}{d}\right)\\ =\sum_{d=1}^{n}g(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}f(i) i=1nh(i)=i=1ndig(d)f(di)=d=1ng(d)i=1dnf(i)

设:
S ( i ) = ∑ j = 1 i f ( j ) S(i)=\sum_{j=1}^{i}f(j) S(i)=j=1if(j)

那么有:
∑ i = 1 n h ( i ) = ∑ d = 1 n g ( d ) S ( ⌊ n d ⌋ ) ∑ i = 1 n h ( i ) = g ( 1 ) S ( n ) + ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ ) g ( 1 ) S ( n ) = ∑ i = 1 n h ( i ) − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ ) S ( n ) = 1 g ( 1 ) ( ∑ i = 1 n h ( i ) − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ ) ) \sum_{i=1}^{n}h(i)=\sum_{d=1}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\\ \sum_{i=1}^{n}h(i)=g(1)S(n)+\sum_{d=2}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\\ g(1)S(n)=\sum_{i=1}^{n}h(i)-\sum_{d=2}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\\ S(n)=\frac{1}{g(1)}\left(\sum_{i=1}^{n}h(i)-\sum_{d=2}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\right)\\ i=1nh(i)=d=1ng(d)S(dn)i=1nh(i)=g(1)S(n)+d=2ng(d)S(dn)g(1)S(n)=i=1nh(i)d=2ng(d)S(dn)S(n)=g(1)1(i=1nh(i)d=2ng(d)S(dn))

递归计算就好了,而且根据取整函数的性质,需要算的前缀和只有 O ( n ) O(\sqrt{n}) O(n )个数 S ( ⌊ n i ⌋ ) S\left(\left\lfloor\frac{n}{i}\right\rfloor\right) S(in).

那么时间复杂度即为:
O ( ∑ i = 1 ⌊ n ⌋ ( i + n i ) ) = O ( n 1 2 ∫ 1 n ( i 1 2 + i − 1 2 ) d i ) = O ( n 3 4 ) O\left(\sum_{i=1}^{\left\lfloor\sqrt{n}\right\rfloor}\left(\sqrt{i}+\sqrt{\frac{n}{i}}\right)\right)=O\left(n^{\frac{1}{2}}\int_{1}^{\sqrt{n}}\left(i^{\frac{1}{2}}+i^{-\frac{1}{2}}\right)\mathrm{d}i\right)=O(n^{\frac{3}{4}}) Oi=1n (i +in )=O(n211n (i21+i21)di)=O(n43)

考虑线性筛预处理前 m m m个数的前缀和,那么时间复杂度变为:
O ( ∑ i = 1 ⌊ n m ⌋ n i ) = O ( n 1 2 ∫ 1 n m i − 1 2 d i ) = O ( n m + m ) O\left(\sum_{i=1}^{\left\lfloor\frac{n}{m}\right\rfloor}\sqrt{\frac{n}{i}}\right)=O\left(n^{\frac{1}{2}}\int_{1}^{\frac{n}{m}}i^{-\frac{1}{2}}\mathrm{d}i\right)=O\left(\frac{n}{\sqrt{m}}+m\right) Oi=1mnin =O(n211mni21di)=O(m n+m)

m = n 2 3 m=n^{\frac{2}{3}} m=n32最优,时间复杂度为 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32).

根据上面的卷积2和卷积3,不难写出杜教筛筛 μ \mu μ ϕ \phi ϕ的前缀和代码.

记忆化使用map实现应该是没有太大问题的,因为需要用map存的值只有 O ( n ) O(\sqrt{n}) O(n )级别个.

luogu4213代码如下(被卡常了两个点,手写hash即可过):

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N=100000,M=5000000;

int b[M+9],pr[M+9],cp;
LL mu[M+9],phi[M+9];

void Sieve(){
  mu[1]=1;phi[1]=1;
  for (int i=2;i<=M;++i){
  	if (!b[i]) pr[++cp]=i,mu[i]=-1,phi[i]=i-1;
    for (int j=1;j<=cp&&i*pr[j]<=M;++j){
      int t=i*pr[j];
	  b[t]=1;
      if (i%pr[j]==0) {mu[t]=0;phi[t]=phi[i]*pr[j];break;}
      mu[t]=-mu[i];phi[t]=phi[i]*(pr[j]-1);
    }
  }
  for (int i=1;i<=M;++i) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}

void start(){
  Sieve();
}

LL n;

void into(){
  scanf("%lld",&n);
}

map<LL,LL>sphi,smu;
LL ans0,ans1;

LL Get_sumphi(LL n){
  if (n<=M) return phi[n];
  if (sphi.find(n)!=sphi.end()) return sphi[n];
  LL res=n*(n+1)>>1;
  for (LL l=2,r;l<=n;l=r+1){
  	r=n/(n/l);
  	res-=(r-l+1)*Get_sumphi(n/l);
  }
  return sphi[n]=res;
}

int Get_summu(LL n){
  if (n<=M) return mu[n];
  if (smu.find(n)!=smu.end()) return smu[n];
  int res=1;
  for (LL l=2,r;l<=n;l=r+1){
  	r=n/(n/l);
  	res-=(r-l+1)*Get_summu(n/l);
  }
  return smu[n]=res;
}

void work(){
  ans0=Get_sumphi(n);
  ans1=Get_summu(n);
}

void outo(){
  printf("%lld %lld\n",ans0,ans1);
}

int main(){
  int T;
  scanf("%d",&T);
  start();
  for (;T--;){
    into();
    work();
    outo();
  }
  return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值