#include<bits/stdc++.h>
#define XD 114514
#define MAXN 50010
#define int long long
using namespace std;
int T,n,m,ans;
bool vis[MAXN];
int mu[MAXN],sum[MAXN],num[MAXN];
vector<int> prm;
void sieve(){
mu[1]=1;sum[1]=1;
for(int i=2;i<=5e4;i++){
if(!vis[i]){
prm.push_back(i);
mu[i]=-1;
}
for(int j=0;j<prm.size() and prm[j]*i<=5e4;j++){
vis[i*prm[j]]=true;
if(i%prm[j]==0) break;
mu[i*prm[j]]=-mu[i];
}
sum[i]=sum[i-1]+mu[i];
}
for(int i=1;i<=5e4;i++){
int r,nem=0;
for(int l=1;l<=i;l=r+1){
r=i/(i/l);
nem+=(r-l+1)*(i/l);
}
num[i]=nem;
}
}
void calc(){
int r;
for(int l=1;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(sum[r]-sum[l-1])*num[n/l]*num[m/l];
}
}
signed main(){
cin>>T;
sieve();
while(T--){
ans=0;
cin>>n>>m;
if(n>m) swap(n,m);
calc();
cout<<ans<<"\n";
}
return 0;
}
P3768 简单的数学题
求:
\sum\limits_{i=1}^n\sum\limits_{j=1}^{n}ij\gcd(i,j)\sum\limits_{i=1}^n\sum\limits_{j=1}^{n}ij\sum\limits_{d=1}^n\varphi(d)[d|i][d|j]\sum\limits_{d=1}^n\varphi(d)\sum\limits_{i=1}^ni[d|i]\sum\limits_{j=1}^{n}j[d|j]\sum\limits_{d=1}^n\varphi(d)\sum\limits_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}i\times d\sum\limits_{j=1}^{\left\lfloor\frac{n}{d}\right\rfloor}j\times d
为方便,设 m=\left\lfloor\frac{n}{d}\right\rfloor。
\sum\limits_{d=1}^n\varphi(d)d^2\times\frac{m^2(m+1)^2}{4}
设 $f=\varphi\times id \times id$,$g=id \times id$,则:
$$\begin{aligned}(h*g)(n)&=\sum\limits_{d|n}f(d)g(\frac{n}{d})\\&=\sum\limits_{d|n}\varphi(d)\times d^2\times (\frac{n}{d})^2\\&=n^2\times \sum\limits_{d|n}\varphi(d)\\&=n^3\end{aligned}$$
所以用杜教筛后数论分块即可。
```cpp
#include<bits/stdc++.h>
#define XD 114514
#define MAXN 5000010
#define int long long
using namespace std;
int p,n,ans;
int inv4,inv6;
int phi[MAXN],sumphi[MAXN];
bool vis[MAXN];
vector<int> prm;
void sieve(){
phi[1]=sumphi[1]=1;
for(int i=2;i<=5e6;i++){
if(!vis[i]){
prm.push_back(i);
phi[i]=i-1;
}
sumphi[i]=(sumphi[i-1]+phi[i]*i%p*i%p)%p;
for(auto j:prm){
if(i*j>5e6) break;
vis[i*j]=true;
if(i%j==0){
phi[i*j]=phi[i]*j;
break;
}
phi[i*j]=phi[i]*phi[j];
}
}
}
int power(int x,int y){
int nem=1;
while(x){
if(x&1) nem=(nem*y)%p;
y=(y*y)%p;x>>=1;
}
return nem;
}
int pow2(int x){
x%=p;return x*(x+1)%p*(2*x+1)%p*inv6%p;
}
int pow3(int x){
x%=p;return x*x%p*(x+1)%p*(x+1)%p*inv4%p;
}
map<int,int> mphi;
int getphi(int x){
if(x<=5e6) return sumphi[x];
if(mphi[x]) return mphi[x];
int nem=pow3(x),r;
for(int l=2;l<=x;l=r+1){
r=x/(x/l);
nem=(nem-((pow2(r)-pow2(l-1)+p)%p*getphi(x/l)%p)%p+p)%p;
}
return mphi[x]=(nem%p+p)%p;
}
signed main(){
cin>>p>>n;
sieve();
inv4=power(p-2,4);
inv6=power(p-2,6);
int r;
for(int l=1;l<=n;l=r+1){
r=n/(n/l);
ans=(ans+((getphi(r)-getphi(l-1))%p+p)%p*pow3(n/l))%p;
}
cout<<(ans%p+p)%p;
return 0;
}
```
## 学习建议
建议看以下的博客,讲的非常好,~~反正我的也看不懂~~。QWQ
[浅谈莫反](https://www.cnblogs.com/orzz/p/15678931.html)
[狄利克雷卷积和莫比乌斯反演](https://zhuanlan.zhihu.com/p/390895860)
(我本人最推荐这两个。QWQ)
[莫比乌斯反演-让我们从基础开始(洛谷日报上的)](https://www.luogu.com.cn/blog/An-Amazing-Blog/mu-bi-wu-si-fan-yan-ji-ge-ji-miao-di-dong-xi)
[莫比乌斯反演](https://www.cnblogs.com/Kong-Ruo/p/7789138.html)
[peng-ym 的杜教筛](https://www.cnblogs.com/peng-ym/p/9446555.html)
[算法学习笔记(35): 狄利克雷卷积](https://zhuanlan.zhihu.com/p/137619492)