传送门
设
f
(
n
)
=
∑
i
=
1
n
∑
j
=
1
n
[
l
c
m
(
i
,
j
)
≤
n
]
f(n)=\sum_{i=1}^{n}\sum_{j=1}^n[lcm(i,j)\le n]
f(n)=∑i=1n∑j=1n[lcm(i,j)≤n],题目让我们求的其实是
∑
i
=
1
b
∑
j
=
1
i
[
l
c
m
(
i
,
j
)
≤
b
]
−
∑
i
=
1
a
−
1
∑
j
=
1
i
[
l
c
m
(
i
,
j
)
≤
a
−
1
]
\sum_{i=1}^b\sum_{j=1}^i[lcm(i,j)\le b]-\sum_{i=1}^{a-1}\sum_{j=1}^i[lcm(i,j)\le a-1]
∑i=1b∑j=1i[lcm(i,j)≤b]−∑i=1a−1∑j=1i[lcm(i,j)≤a−1],也就是说要求出
∑
i
=
1
n
∑
j
=
1
i
[
l
c
m
(
i
,
j
)
≤
b
]
\sum_{i=1}^n\sum_{j=1}^i[lcm(i,j)\le b]
∑i=1n∑j=1i[lcm(i,j)≤b],但这个式子不太方便我们反演,它其实就是
1
2
(
∑
i
=
1
n
∑
j
=
1
n
[
l
c
m
(
i
,
j
)
≤
n
]
+
∑
i
=
1
n
[
l
c
m
(
i
,
i
)
≤
n
]
)
=
f
(
n
)
+
n
2
\frac 12(\sum_{i=1}^n\sum_{j=1}^n[lcm(i,j)\le n]+\sum_{i=1}^n[lcm(i,i)\le n])=\frac {f(n)+n}2
21(∑i=1n∑j=1n[lcm(i,j)≤n]+∑i=1n[lcm(i,i)≤n])=2f(n)+n,因此我们下面考虑如何求出
f
(
n
)
f(n)
f(n)。
f
(
n
)
=
∑
i
=
1
n
∑
j
=
1
n
[
l
c
m
(
i
,
j
)
≤
n
]
=
∑
k
=
1
n
∑
i
=
1
n
∑
j
=
1
n
[
i
j
k
≤
n
]
[
g
c
d
(
i
,
j
)
=
k
]
=
∑
k
=
1
n
∑
i
=
1
⌊
n
k
⌋
∑
j
=
1
⌊
n
k
⌋
[
i
j
k
≤
n
]
∑
d
∣
i
,
d
∣
j
μ
(
d
)
=
∑
k
=
1
n
∑
i
=
1
n
∑
j
=
1
n
[
i
j
k
≤
n
]
∑
d
∣
i
,
d
∣
j
μ
(
d
)
=
∑
d
=
1
n
μ
(
d
)
∑
k
=
1
n
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
n
d
⌋
[
i
j
k
≤
⌊
n
d
2
⌋
]
=
∑
d
=
1
⌊
n
⌋
μ
(
d
)
∑
k
=
1
⌊
n
d
2
⌋
∑
i
=
1
⌊
n
d
2
⌋
∑
j
=
1
⌊
n
d
2
⌋
[
i
j
k
≤
⌊
n
d
2
⌋
]
=
∑
d
=
1
⌊
n
⌋
μ
(
d
)
g
(
⌊
n
d
2
⌋
)
.
.
.
.
.
令
g
(
n
)
=
∑
k
=
1
n
∑
i
=
1
n
∑
j
=
1
n
[
i
j
k
≤
n
]
\begin{aligned} f(n)&=\sum_{i=1}^n\sum_{j=1}^n[lcm(i,j)\le n]\\ &=\sum_{k=1}^n\sum_{i=1}^n\sum_{j=1}^n[\frac {ij}k\le n][gcd(i,j)=k]\\ &=\sum_{k=1}^n\sum_{i=1}^{\lfloor \frac nk\rfloor}\sum_{j=1}^{\lfloor\frac nk\rfloor}[ijk\le n]\sum_{d\mid i,d\mid j}\mu(d)\\ &=\sum_{k=1}^n\sum_{i=1}^{n}\sum_{j=1}^{n}[ijk\le n]\sum_{d\mid i,d\mid j}\mu(d)\\ &=\sum_{d=1}^n\mu(d)\sum_{k=1}^n\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}[ijk\le \lfloor\frac n{d^2}\rfloor]\\ &=\sum_{d=1}^{\lfloor\sqrt n\rfloor}\mu(d)\sum_{k=1}^{\lfloor \frac n{d^2}\rfloor}\sum_{i=1}^{\lfloor\frac n{d^2}\rfloor}\sum_{j=1}^{\lfloor\frac n{d^2}\rfloor}[ijk\le \lfloor\frac n{d^2}\rfloor]\\ &=\sum_{d=1}^{\lfloor\sqrt n\rfloor}\mu(d)g(\lfloor\frac n{d^2}\rfloor).....令g(n)=\sum_{k=1}^n\sum_{i=1}^n\sum_{j=1}^n[ijk\le n] \end{aligned}
f(n)=i=1∑nj=1∑n[lcm(i,j)≤n]=k=1∑ni=1∑nj=1∑n[kij≤n][gcd(i,j)=k]=k=1∑ni=1∑⌊kn⌋j=1∑⌊kn⌋[ijk≤n]d∣i,d∣j∑μ(d)=k=1∑ni=1∑nj=1∑n[ijk≤n]d∣i,d∣j∑μ(d)=d=1∑nμ(d)k=1∑ni=1∑⌊dn⌋j=1∑⌊dn⌋[ijk≤⌊d2n⌋]=d=1∑⌊n⌋μ(d)k=1∑⌊d2n⌋i=1∑⌊d2n⌋j=1∑⌊d2n⌋[ijk≤⌊d2n⌋]=d=1∑⌊n⌋μ(d)g(⌊d2n⌋).....令g(n)=k=1∑ni=1∑nj=1∑n[ijk≤n]
现在考虑如何求
g
(
n
)
g(n)
g(n),根据对称性,我们假设
k
≤
i
≤
j
k\le i\le j
k≤i≤j,于是容易确定
k
∈
[
1
,
⌊
n
1
3
⌋
]
,
i
∈
[
k
,
⌊
n
k
⌋
]
,
j
∈
[
i
,
⌊
n
i
k
⌋
]
k\in[1,\lfloor n^{\frac 13}\rfloor],i\in[k,\lfloor \sqrt{\frac nk}\rfloor],j\in[i,\lfloor\frac n{ik}\rfloor]
k∈[1,⌊n31⌋],i∈[k,⌊kn⌋],j∈[i,⌊ikn⌋],枚举量大概是
O
(
n
+
n
2
+
n
3
+
.
.
.
+
n
n
1
3
)
=
O
(
∫
1
n
1
3
n
x
d
x
)
=
O
(
n
2
3
)
O(\sqrt n+\sqrt{\frac n2}+\sqrt{\frac n3}+...+\sqrt{\frac n{n^{\frac 13}}})=O(\int_{1}^{n^{\frac 13}} \sqrt{\frac nx}\, {\rm d}x)=O(n^{\frac 23})
O(n+2n+3n+...+n31n)=O(∫1n31xndx)=O(n32),然后枚举的时候分三种情况计算贡献即可
k
<
i
<
j
k<i<j
k<i<j时要算6,
k
=
i
<
j
或
k
<
i
=
j
k=i<j或k<i=j
k=i<j或k<i=j时要算3,
k
=
i
=
j
k=i=j
k=i=j时要算1。
总复杂度的话就是 O ( ∑ d = 1 n ( n d 2 ) 2 3 ) = O ( n 2 3 ) O(\sum_{d=1}^{\sqrt n}{(\frac n{d^2})}^{\frac 23})=O(n^{\frac 23}) O(∑d=1n(d2n)32)=O(n32),你可以理解为杜教筛外面套了个 O ( n ) O(\sqrt n) O(n)的分块,因此复杂度不变。
int prim[maxn],tot,mu[maxn];
bool flag[maxn];
void init(int n){
mu[1]=1;
FOR(i,2,n+1){
if(!flag[i])prim[tot++]=i,mu[i]=-1;
for(register int j=0;j<tot && prim[j]*i<=n;++j){
flag[i*prim[j]]=1;
if(i%prim[j]==0)break;
mu[i*prim[j]]=-mu[i];
}
}
}
ll get(ll n){
register int limt1 = pow(n,1.0/3.0),limt2;
register ll ans=0,c,up;
while(1ll*limt1*limt1*limt1<=n)limt1++;
while(1ll*limt1*limt1*limt1>n)limt1--;
FOR(k,1,limt1+1){
c=n/k;
limt2=(int)(sqrt(c)+0.5);
FOR(i,k,limt2+1){
up=c/i;
if(up<i)break;
if(i==k){
ans+=3ll*(up-i)+1ll;
}else{
ans+=6ll*(up-i)+3ll;
}
}
}
return ans;
}
ll cal(ll n){
if(!n)return 0;
register int limt = sqrt(n);
register ll ans=0;
FOR(i,1,limt+1)ans+=mu[i]*get(n/(1ll*i*i));
return (ans+n)>>1;
}
int main(){
ll a,b;
rd(&a,&b);
init((int)sqrt(b));
wrn(cal(b)-cal(a-1));
}