【[SDOI2015]约数个数和】
给定 n , m n,m n,m,求下面式子的值,其中 σ 0 ( i ) \sigma_0(i) σ0(i)表示 i i i的约数个数。
∑ i = 1 n ∑ j = 1 m σ 0 ( i j ) \sum_{i=1}^n\sum_{j=1}^m\sigma_0(ij) i=1∑nj=1∑mσ0(ij)
其中 n , m ≤ 50000 n,m\leq 50000 n,m≤50000
我们考虑将 σ 0 ( i j ) \sigma_0(ij) σ0(ij)进行转化,其实其值就相当于下面:
σ 0 ( i j ) = ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] \sigma_0(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1] σ0(ij)=x∣i∑y∣j∑[gcd(x,y)=1]
简单证明:
由于其质因子之间会不影响,所以我们分开单独考虑,对于一个 i j ij ij的质因子 p p p,假设它在 i j ij ij中为 p c p^c pc,那么肯定有 p a ∣ i , p b ∣ j , a + b = c p^a|i,p^b|j,a+b=c pa∣i,pb∣j,a+b=c,所以我们考虑,对于一个因子 p d p^d pd,如果 d ≤ a d\leq a d≤a我们就在 i i i中选择,此时 p d ∣ x p^d|x pd∣x,那么由于对于这一个因子只能算一次,所以在 x x x中选了后就不能再 y y y中选择,所以必须保证 y y y中没有因子 p p p,而当 d > a d> a d>a时,我们就在 y y y中选择指数为 d − a d-a d−a的,此时同样要求 x x x中不包含因子 p p p,那么将此情况应用到所有的质因子上,显然 x ⊥ y x\perp y x⊥y,也就是 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1,因此得证。
其实相当于一个映射,我们将 p d p^d pd,其中 d ≤ a d\leq a d≤a的映射到 x x x上去,而 d > a d> a d>a的映射到 y y y上,由于如果 x , y x,y x,y不互质,那么相当于我们把同一个因子同时映射在了 x , y x,y x,y,会算多次,但是只能算一次,所以要保证互质。
那么我们就将式子转换成了(这里默认 n ≤ m n\leq m n≤m不满足则交换):
∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] ∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j ∑ w ∣ x , w ∣ y μ ( w ) ∑ w = 1 n μ ( w ) ∑ i = 1 ⌊ n w ⌋ ∑ j = 1 ⌊ m w ⌋ ⌊ n w i ⌋ ⌊ m w j ⌋ \sum_{i=1}^n\sum_{j=1}^m\sum_{x|i}\sum_{y|j}[gcd(x,y)=1] \\ \sum_{i=1}^n\sum_{j=1}^m\sum_{x|i}\sum_{y|j}\sum_{w|x,w|y}\mu(w) \\ \sum_{w=1}^n\mu(w)\sum_{i=1}^{\lfloor\frac{n}{w}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{w}\rfloor}\left\lfloor\frac{n}{wi}\right\rfloor\left\lfloor\frac{m}{wj}\right\rfloor i=1∑nj=1∑mx∣i∑y∣j∑[gcd(x,y)=1]i=1∑nj=1∑mx∣i∑y∣j∑w∣x,w∣y∑μ(w)w=1∑nμ(w)i=1∑⌊wn⌋j=1∑⌊wm⌋⌊win⌋⌊wjm⌋
由于 n , m n,m n,m的范围比较小,我们线性筛出 μ \mu μ并预处理前缀和,然后对于后面的我们令 g ( n ) = ∑ i = 1 n ⌊ n i ⌋ g(n)=\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor g(n)=∑i=1n⌊in⌋
其实我们容易知道:
g ( n ) = ∑ i = 1 n ⌊ n i ⌋ = ∑ i = 1 n σ 0 ( i ) g(n)=\sum_{i=1}^n\left\lfloor\frac{n}{i}\right\rfloor=\sum_{i=1}^n\sigma_0(i) g(n)=i=1∑n⌊in⌋=i=1∑nσ0(i)
简单证明:
我们考虑,对于一个 i i i,它可以对其倍数,也就是 2 i , 3 i , ⋯   , ⌊ n i ⌋ i 2i,3i,\cdots,\lfloor\frac{n}{i}\rfloor i 2i,3i,⋯,⌊in⌋i,贡献 ⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊in⌋次,刚好反过来考虑,对于一个数 i i i,它的每个因子都会对其贡献一次,所以原式就相等了。
原式就变成:
∑ w = 1 n μ ( w ) g ( ⌊ n w ⌋ ) g ( ⌊ m w ⌋ ) \sum_{w=1}^n\mu(w)g(\lfloor\frac{n}{w}\rfloor)g(\lfloor\frac{m}{w}\rfloor) w=1∑nμ(w)g(⌊wn⌋)g(⌊wm⌋)
那么我们再 O ( n ) O(n) O(n)的线性筛出 σ 0 \sigma_0 σ0并预处理前缀和,这个题就可以每次分块的回答了。
复杂度 O ( n + T n ) O(n+T\sqrt n) O(n+Tn)
#include
#include
#include
#define ll long long
using namespace std;
const int M=1e5+10;
int T,n,m;
ll prime[M],sdiv[M],num[M],cnt,mob[M];
bool nop[M];
void init(int n){
sdiv[1]=1;num[1]=1;mob[1]=1;
for(int i=2;i<=n;i++){
if(!nop[i]) prime[++cnt]=i,sdiv[i]=2,num[i]=1,mob[i]=-1;
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
nop[i*prime[j]]=1;
if(i%prime[j]){
sdiv[i*prime[j]]=sdiv[i]*sdiv[prime[j]];
num[i*prime[j]]=1;
mob[i*prime[j]]=-mob[i];
}else{
sdiv[i*prime[j]]=sdiv[i]/(num[i]+1)*(num[i]+2);
num[i*prime[j]]=num[i]+1;
mob[i*prime[j]]=0;
break;
}
}
}
for(int i=1;i<=n;i++) sdiv[i]+=sdiv[i-1],mob[i]+=mob[i-1];
}
ll calc(int n,int m){
int pos;if(n>m) swap(n,m);
ll ans=0;
for(int i=1;i<=n;i=pos+1){
int t1=n/i,t2=m/i;
pos=min(n/(t1),m/(t2));
ans+=(mob[pos]-mob[i-1])*(sdiv[t1])*(sdiv[t2]);
}
return ans;
}
int main(){
scanf("%d",&T);
init(50000);
while(T--){
scanf("%d%d",&n,&m);
printf("%lld\n",calc(n,m));
}
return 0;
}
加强版【BZOJ4176-权限题】
一组询问,给定 n ≤ 1 0 9 n\leq 10^9 n≤109,求下面式子的值:
∑ i = 1 n ∑ j = 1 n σ 0 ( i j ) \sum_{i=1}^n\sum_{j=1}^n\sigma_0(ij) i=1∑nj=1∑nσ0(ij)
此时无法 O ( n ) O(n) O(n)的线性筛,所以我们要换个角度考虑,可能要用杜教筛或其他低于线性的筛法。
我们先来看 σ 0 ( i j ) \sigma_0(ij) σ0(ij),对于一个 d ∣ i j d|ij d∣ij,我们令 a = i g c d ( i , d ) , b = d g c d ( i , d ) a=\frac{i}{gcd(i,d)},b=\frac{d}{gcd(i,d)} a=gcd(i,d)i,b=gcd(i,d)d,此时显然 a ⊥ b a\perp b a⊥b,然后肯定有 a ∣ i , b ∣ j a|i,b|j a∣i,b∣j( a ∣ i a|i a∣i是显然的,而 b ∣ j b|j b∣j由于 d ∣ i j d|ij d∣ij而 b ∣ d b|d b∣d, b b b只是除去了在 i i i中的因子,所以肯定 b ∣ j b|j b∣j)。
另外一种解释: b × g c d ( i , d ) = d b\times gcd(i,d)=d b×gcd(i,d)=d, d ∣ i j ⇔ b ∣ i j g c d ( i , d ) = b ∣ a j d|ij\Leftrightarrow b|\frac{ij}{gcd(i,d)} = b|aj d∣ij⇔b∣gcd(i,d)ij=b∣aj,因为 a ⊥ b a\perp b a⊥b,所以 b ∣ j b|j b∣j。
所以,对于任意 a ⊥ b , a ∣ i , b ∣ j a\perp b,a|i,b|j a⊥b,a∣i,b∣j的都有 d = i b a ∣ i j d=\frac{ib}{a}|ij d=aib∣ij,由此可知:
σ 0 ( i j ) = ∑ d ∣ i j 1 = ∑ a ∣ i , b ∣ j , a ⊥ b 1 = ∑ a ∣ i , b ∣ j [ g c d ( i , j ) = 1 ] \sigma_0(ij)=\sum_{d|ij}1=\sum_{a|i,b|j,a\perp b}1=\sum_{a|i,b|j}[gcd(i,j)=1] σ0(ij)=d∣ij∑1=a∣i,b∣j,a⊥b∑1=a∣i,b∣j∑[gcd(i,j)=1]
这个也就是前面的另一种数学的证明方法,再说一遍而已XD
我们看原来化简到最后的式子,此时就变成了:
∑ w = 1 n μ ( w ) ( g ( ⌊ n w ⌋ ) ) 2 \sum_{w=1}^n\mu(w)(g\left(\left\lfloor\frac{n}{w}\right\rfloor\right))^2 w=1∑nμ(w)(g(⌊wn⌋))2
对于 μ \mu μ的前缀和我们用杜教筛就可以了,而对于 g ( n ) g(n) g(n)的值,我们预处理 n 2 3 n^{\frac{2}{3}} n32个,然后每次调用到更大的,现场数论分块 O ( n ) O(\sqrt n) O(n)的算就好啦,记忆化一下。
由于杜教筛中也有数论分块,所以复杂度还是 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32),那么这个题就解决了。
代码,先咕咕一会儿XD
一道类似的题目【51Nod1220约数之和】-【题解】