求 ∑i=1n∑j=1mlcm(i,j) ∑ i = 1 n ∑ j = 1 m l c m ( i , j )
显然
原式变成
我们换成去枚举 gcd g c d ,可以得到
再去枚举gcd,得到
#include
#include
#include
using namespace std;
#define mod 20101009
#define N 10000010
#define ll long long
int prime[N],n,m,tot=0;
ll mu[N],ans=0;
bool notprime[N];
void mobius(){
mu[1]=1;
memset(notprime,false,sizeof(notprime));
for(int i=2;i<=n;i++){
if(!notprime[i]){
mu[i]=-1;
prime[++tot]=i;
}for(int j=1;j<=tot,prime[j]*i<=n;j++){
notprime[prime[j]*i]=true;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}mu[prime[j]*i]=-mu[i];
}
}for(int i=2;i<=n;i++) mu[i]=(mu[i-1]+mu[i]*i%mod*i%mod)%mod;
}
ll sum(int x,int y){return ((ll)(x+y)*(y-x+1)/2)%mod;}
ll f(int a,int b){
if(a>b) swap(a,b);
ll ans1=0;
for(int i=1,last=1;i<=a;i=last+1){
last=min(a/(a/i),b/(b/i));
ans1=(ans1+(mu[last]-mu[i-1]+mod)%mod*sum(1,a/i)%mod*sum(1,b/i)%mod)%mod;
}return ans1;
}
int main(){
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
mobius();
for(int i=1,last=1;i<=n;i=last+1){
last=min(n/(n/i),m/(m/i));
ans=(ans+f(n/i,m/i)%mod*sum(i,last))%mod;
}printf("%lld",ans);
return 0;
}