题目描述:戳这里
题解:
1
a
+
1
b
=
1
c
\frac{1}{a}+\frac{1}{b}=\frac{1}{c}
a1+b1=c1
(
a
+
b
)
c
=
a
b
(a+b)c=ab
(a+b)c=ab
令
g
=
g
c
d
(
a
,
b
)
,
A
=
a
g
,
B
=
b
g
令g=gcd(a,b),A=\frac{a}{g},B=\frac{b}{g}
令g=gcd(a,b),A=ga,B=gb
(
A
+
B
)
c
=
A
B
g
(A+B)c=ABg
(A+B)c=ABg
由
于
g
要
整
除
等
式
左
边
的
东
西
,
然
而
g
不
整
除
c
,
所
以
g
整
除
A
+
B
,
那
么
可
以
除
过
去
由于g要整除等式左边的东西,然而g不整除c,所以g整除A+B,那么可以除过去
由于g要整除等式左边的东西,然而g不整除c,所以g整除A+B,那么可以除过去
A
+
B
g
=
A
B
c
\frac{A+B}{g}=\frac{AB}{c}
gA+B=cAB
我们假设这个式子两边都等于p。
那么如果
p
!
=
1
p!=1
p!=1,说明p整除A或者B,p不可能同时整除A和B,因为A、B互质。但是p要整除
A
+
B
A+B
A+B,所以不可能成立。
所以可以推出
p
=
1
p=1
p=1。
那么就可以推出两条式子:
A
+
B
=
g
,
即
是
:
a
+
b
=
g
2
A+B=g,即是:a+b=g^2
A+B=g,即是:a+b=g2
c
=
A
B
,
就
是
:
c
=
a
b
g
2
c=AB,就是:c=\frac{ab}{g^2}
c=AB,就是:c=g2ab
那么接下来问题就比较好处理了:
由于
a
,
b
<
=
1
0
12
a,b<=10^{12}
a,b<=1012,那么
a
+
b
=
2
∗
1
0
12
=
1
0
6
级
别
\sqrt{a+b}=\sqrt{2*10^{12}}=10^6级别
a+b=2∗1012=106级别
我们先枚举gcd(a,b)=g,然后假设a=i*g,那么可以列出和式:
∑
g
=
1
2
n
∑
i
=
1
⌊
n
g
⌋
[
g
c
d
(
i
g
,
g
2
−
i
g
)
=
g
]
\sum_{g=1}^{\sqrt{2n}}\sum_{i=1}^{\lfloor{\frac{n}{g}}\rfloor}[gcd(ig,g^2-ig)=g]
g=1∑2ni=1∑⌊gn⌋[gcd(ig,g2−ig)=g]
化简一下:
∑
g
=
1
2
n
∑
i
=
1
⌊
n
g
⌋
[
g
c
d
(
i
,
g
−
i
)
=
1
]
\sum_{g=1}^{\sqrt{2n}}\sum_{i=1}^{\lfloor{\frac{n}{g}}\rfloor}[gcd(i,g-i)=1]
g=1∑2ni=1∑⌊gn⌋[gcd(i,g−i)=1]
由于辗转相减的性质,可知:
∑
g
=
1
2
n
∑
i
=
1
⌊
n
g
⌋
[
g
c
d
(
i
,
g
)
=
1
]
\sum_{g=1}^{\sqrt{2n}}\sum_{i=1}^{\lfloor{\frac{n}{g}}\rfloor}[gcd(i,g)=1]
g=1∑2ni=1∑⌊gn⌋[gcd(i,g)=1]
即是求一定范围内与g互质的数的个数。
前面还有一些小问题,实际上我们对i的限制范围有一些不准确。
1
<
=
g
2
−
i
g
<
=
n
1<=g^2-ig<=n
1<=g2−ig<=n
g
−
⌊
n
g
⌋
<
=
i
<
=
g
−
1
g-\lfloor\frac{n}{g}\rfloor<=i<=g-1
g−⌊gn⌋<=i<=g−1
与原范围合并一下,可以化简为:
m
a
x
(
1
,
g
−
⌊
n
g
⌋
)
<
=
i
<
=
m
i
n
(
g
−
1
,
⌊
n
g
⌋
)
max(1,g-\lfloor\frac{n}{g}\rfloor)<=i<=min(g-1,\lfloor\frac{n}{g}\rfloor)
max(1,g−⌊gn⌋)<=i<=min(g−1,⌊gn⌋)
所以原式可以写成:
∑
g
=
1
2
n
∑
i
=
m
a
x
(
1
,
g
−
⌊
n
g
⌋
)
m
i
n
(
g
−
1
,
⌊
n
g
⌋
)
[
g
c
d
(
i
,
g
)
=
1
]
\sum_{g=1}^{\sqrt{2n}}\sum_{i=max(1,g-\lfloor\frac{n}{g}\rfloor)}^{min(g-1,\lfloor\frac{n}{g}\rfloor)}[gcd(i,g)=1]
g=1∑2ni=max(1,g−⌊gn⌋)∑min(g−1,⌊gn⌋)[gcd(i,g)=1]
接下来只要求
g
c
d
(
i
,
g
)
=
1
gcd(i,g)=1
gcd(i,g)=1的对数了。
这个可以直接用莫比乌斯反演,对r搞一下,l-1搞一下,然后相减即可。
时间复杂度
O
(
n
l
o
g
(
n
)
)
O(\sqrt{n}log(\sqrt{n}))
O(nlog(n))
代码如下:
#pragma GCC optimze("Ofast","inline")
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e6+5;
ll n,ans;
int mu[maxn],su[maxn],lnk[maxn],nxt[16*maxn],son[16*maxn],tot;
bool vis[maxn];
void make_mu(){
mu[1]=1; int m=0;
for (int i=2;i<=2e6;i++){
if (!vis[i]) su[++m]=i,mu[i]=-1;
for (int j=1;j<=m&&1ll*su[j]*i<=2e6;j++){
vis[i*su[j]]=1;
if (i%su[j]==0) {mu[i*su[j]]=0; break;}
else mu[i*su[j]]=-mu[i];
}
}
}
ll doit(ll x,ll y){
ll ret=0;
for (int j=lnk[y];j;j=nxt[j])
if (y%son[j]==0) ret+=mu[son[j]]*(x/son[j]);
return ret;
}
void add(int x,int y){
son[++tot]=y,nxt[tot]=lnk[x],lnk[x]=tot;
}
int main(){
scanf("%lld",&n);
make_mu();
for (int i=1;1ll*i*i<=2*n;i++)
if(mu[i])
for (int j=1;1ll*j*i*j*i<=2*n;j++)
add(i*j,i);
for (ll g=1ll;g*g<=2*n;g++)
ans+=doit(min(n/g,g-1),g)-doit(max(1ll,g-n/g)-1,g);
printf("%lld\n",ans);
return 0;
}