对原式运用莫比乌斯函数进行转化得到原式=
然后直接暴力就好了。时间复杂度O(NlogN)。
AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define p 1000000007
#define N 500005
using namespace std;
int m,n,cnt,c[N],mu[N],a[N],sum[N]; bool vis[N];
int ksm(int x,int y){
int t=1; for (; y; y>>=1,x=(ll)x*x%p) if (y&1) t=(ll)t*x%p; return t;
}
void pfs(){
int i,j; mu[1]=1;
for (i=2; i<=n; i++){
if (!vis[i]){ mu[i]=-1; c[++cnt]=i; }
for (j=1; j<=cnt && i*c[j]<=n; j++){
vis[i*c[j]]=1;
if (i%c[j]) mu[i*c[j]]=-mu[i]; else{
mu[i*c[j]]=0; break;
}
}
}
}
int main(){
scanf("%d%d",&m,&n); int i,j,ans=0;
if (m>n) swap(m,n); pfs();
for (i=1; i<=n; i++) a[i]=1;
for (i=1; i<=m; i++){
int x=ksm(i,i),y=0;
for (j=1; j*i<=n; j++){
a[j]=(ll)a[j]*j%p; sum[j]=(sum[j-1]+a[j])%p;
}
for (j=1; j*i<=m; j++) if (mu[j])
y=((ll)a[j]*a[j]%p*sum[m/i/j]%p*sum[n/i/j]%p*mu[j]+y+p)%p;
ans=(ans+(ll)x*y%p)%p;
}
printf("%d\n",ans);
return 0;
}
by lych
2016.2.23