題目大意
給定n,m,求:
Solution
令p=gcd(i,j),且min{n,m}=n。
令q=dp,S(n)=
則原式=
令F(q)=
則原式=
其實F類似積性函數,可以用線性篩可以把它求出來。
代碼
#include<cstdio>
#include<algorithm>
#define mo 20101009
using namespace std;
typedef long long ll;
int prime[10000010],flag[10000010];
ll F[10000010],S[10000010];
int main()
{
int n,m,cnt=0;
scanf("%d%d",&n,&m);
flag[1]=1;
int MAX=max(n,m);
int MIN=min(n,m);
F[1]=1;
for (int i=2;i<=MAX;i++)
{
if (!flag[i])
prime[++cnt]=i,F[i]=-i+1;
for (int j=1;j<=cnt;j++)
{
if (prime[j]*i>MAX) break;
flag[i*prime[j]]=1;
if (i%prime[j]==0)
{
F[i*prime[j]]=F[i];
break;
}
F[i*prime[j]]=F[i]*F[prime[j]]%mo;
}
}
for (int i=1;i<=MAX;i++)
{
S[i]=S[i-1]+i;
if (S[i]>=mo) S[i]-=mo;
}
ll ans=0;
for (int q=1;q<=MIN;q++)
{
int n1=n/q,m1=m/q;
ll sum=S[n1]*S[m1]%mo;
sum*=q;
sum%=mo;
sum*=F[q];
sum%=mo;
sum=(sum+mo)%mo;
ans+=sum;
if (ans>=mo) ans-=mo;
}
printf("%lld\n",ans);
return 0;
}