练习一发LaTeX
a
n
s
=
∑
x
=
1
n
∑
y
=
1
m
2
g
c
d
(
x
,
y
)
−
1
=
∑
x
=
1
n
∑
y
=
1
m
(
−
1
+
2
∑
p
∣
g
c
d
(
x
,
y
)
φ
(
p
)
)
=
2
∑
x
=
1
n
∑
y
=
1
m
∑
p
∣
g
c
d
(
x
,
y
)
φ
(
p
)
−
n
∗
m
=
2
∑
p
=
1
m
i
n
(
n
,
m
)
φ
(
p
)
∑
x
=
1
n
∑
y
=
1
m
[
p
∣
x
]
[
p
∣
y
]
−
n
∗
m
=
2
∑
p
=
1
m
i
n
(
n
,
m
)
φ
(
p
)
⌊
n
p
⌋
⌊
m
p
⌋
−
n
∗
m
\begin{aligned}ans &= \sum_{x=1}^n\sum_{y=1}^m2gcd(x,y)-1\\ &=\sum_{x=1}^n\sum_{y=1}^m\left(-1+2\sum_{p|gcd(x,y)}\varphi(p)\right)\\ &=2\sum_{x=1}^n\sum_{y=1}^m\sum_{p|gcd(x,y)}\varphi(p) - n*m\\ &=2\sum_{p=1}^{min(n,m)}\varphi(p)\sum_{x=1}^n\sum_{y=1}^m[p|x][p|y] - n*m\\ &=2\sum_{p=1}^{min(n,m)}\varphi(p)\lfloor\frac np\rfloor \lfloor\frac mp\rfloor - n*m\end{aligned}
ans=x=1∑ny=1∑m2gcd(x,y)−1=x=1∑ny=1∑m⎝⎛−1+2p∣gcd(x,y)∑φ(p)⎠⎞=2x=1∑ny=1∑mp∣gcd(x,y)∑φ(p)−n∗m=2p=1∑min(n,m)φ(p)x=1∑ny=1∑m[p∣x][p∣y]−n∗m=2p=1∑min(n,m)φ(p)⌊pn⌋⌊pm⌋−n∗m
这个搁今天得整除分块后杜教筛1e10+多组数据
AC Code:
#include<bits/stdc++.h>
#define maxn 100005
#define LL long long
using namespace std;
int n,m,phi[maxn],pr[maxn/8],cnt_pr;
bool vis[maxn];
int main()
{
scanf("%d%d",&n,&m); if(n>m) swap(n,m);
phi[1] = 1;
LL ans = 1ll*n*m;
for(int i=2;i<=n;i++)
{
if(!vis[i]) pr[cnt_pr++] = i , phi[i]=i-1;
for(int j=0;pr[j]*i<=n;j++)
{
vis[pr[j] * i] = 1;
if(i % pr[j] == 0){ phi[i*pr[j]]=phi[i]*pr[j];break; }
phi[i*pr[j]] = phi[i] * phi[pr[j]];
}
ans += 1ll*(2*phi[i])*(n/i)*(m/i);
}
printf("%lld\n",ans);
}
upd:自己杠精了。
∑
i
=
1
n
∑
j
=
1
n
j
φ
(
i
)
=
∑
j
=
1
n
∑
i
=
1
n
j
φ
(
i
)
=
∑
j
=
1
n
Φ
(
n
j
)
=
∑
i
=
1
n
i
=
n
(
n
+
1
)
2
\begin{aligned} \sum_{i=1}^n\sum_{j=1}^{\frac nj} \varphi(i) = \sum_{j=1}^n\sum_{i=1}^{\frac nj} \varphi(i) = \sum_{j=1}^n \Phi(\frac nj) = \sum_{i=1}^n i = \frac {n(n+1)}2 \end{aligned}
i=1∑nj=1∑jnφ(i)=j=1∑ni=1∑jnφ(i)=j=1∑nΦ(jn)=i=1∑ni=2n(n+1)
AC Code:
#include<bits/stdc++.h>
#define maxn 100005
#define LL long long
using namespace std;
int n,m,phi[maxn],pr[maxn/8],cnt_pr;
bool vis[maxn];
map<int,LL>mp;
LL solve(int now)
{
if(now <= 2137) return phi[now];
if(mp.count(now)) return mp[now];
LL &ret=mp[now]=1ll*now*(now+1)/2;
for(int i=2,nxt;i<=now;i=nxt+1)
{
int tmp = now/i;
nxt = now / tmp;
ret -= solve(tmp) * (nxt-i+1);
}
return ret;
}
int main()
{
scanf("%d%d",&n,&m); if(n>m) swap(n,m);
phi[1] = 1;
LL ans = -1ll*n*m;
for(int i=2;i<=min(n,2137);i++)
{
if(!vis[i]) pr[cnt_pr++] = i , phi[i]=i-1;
for(int j=0;pr[j]*i<=n;j++)
{
vis[pr[j] * i] = 1;
if(i % pr[j] == 0){ phi[i*pr[j]]=phi[i]*pr[j];break; }
phi[i*pr[j]] = phi[i] * (pr[j]-1);
}
phi[i] += phi[i-1];
}
for(int i=1,nxt,psolve=0,tmp,div1,div2;i<=n;i=nxt+1)
{
div1 = n / i , div2 = m / i;
nxt = min(n/div1,m/div2);
ans += 2ll * ((tmp=solve(nxt))-psolve) * div1 * div2;
psolve = tmp;
}
printf("%lld\n",ans);
}