能量采集
题目
解析
提取题意:求
∑
i
=
1
n
∑
j
=
1
m
2
∗
g
c
d
(
i
,
j
)
+
1
\sum_{i=1}^{n}\sum_{j=1}^{m}2*gcd(i,j)+1
∑i=1n∑j=1m2∗gcd(i,j)+1
提取常数项得
n
∗
m
+
2
∗
∑
i
=
1
n
∑
j
=
1
m
g
c
d
(
i
,
j
)
n*m+2*\sum_{i=1}^{n}\sum_{j=1}^{m}gcd(i,j)
n∗m+2∗∑i=1n∑j=1mgcd(i,j)
不妨设n<=m,考虑利用欧拉函数的性质:
∑
d
∣
n
ϕ
(
d
)
=
n
\sum_{d\mid n}\phi(d)=n
∑d∣nϕ(d)=n
把性质套进去得
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
i
,
d
∣
j
ϕ
(
d
)
\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d\mid i,d\mid j}\phi(d)
i=1∑nj=1∑md∣i,d∣j∑ϕ(d)
倍数法优化得
∑
i
=
1
n
ϕ
(
i
)
∗
⌊
n
d
⌋
∗
⌊
m
d
⌋
\sum_{i=1}^{n}\phi(i)*⌊\frac{n}{d}⌋*⌊\frac{m}{d}⌋
i=1∑nϕ(i)∗⌊dn⌋∗⌊dm⌋
O
(
n
)
O(n)
O(n)预处理欧拉函数,再套整除分块
O
(
n
)
O(\sqrt n)
O(n
),这个题目就
O
(
m
i
n
(
n
,
m
)
)
O(min(n,m))
O(min(n,m))的解决了PS:似乎可以用杜教筛的方式提高效率
本题有莫比乌斯反演
O
(
m
i
n
(
n
,
m
)
)
O(min(n,m))
O(min(n,m))/容斥
O
(
n
log
n
)
?
O
(
n
log
log
n
)
?
O(n\log n)?O(n\log \log n)?
O(nlogn)?O(nloglogn)?的做法,此处省略
code:
#include<cstdio>
#define rr register int
#define int long long
using namespace std;
inline int min(int x,int y){return x<y?x:y;}
int n,m,ans,phi[100010],pr[100010],tot;
bool vis[100010];
signed main()
{
scanf("%lld%lld",&n,&m),phi[1]=1;
if(n>m)n^=m^=n^=m;
for(rr i=2;i<=n;++i)
{
if(!vis[i])pr[++tot]=i,phi[i]=i-1;
for(rr j=1;j<=tot&&pr[j]*i<=n;++j)
{
vis[pr[j]*i]=1;
if(!(i%pr[j])){phi[i*pr[j]]=phi[i]*pr[j];break;}
phi[i*pr[j]]=(pr[j]-1)*phi[i];
}
}
for(rr i=2;i<=n;++i)phi[i]+=phi[i-1];
for(rr l=1,r;l<=n;l=r+1)ans+=(phi[r=min(n/(n/l),m/(m/l))]-phi[l-1])*(n/l)*(m/l);
printf("%lld",(ans<<1)-n*m);
return 0;
}