题意:求
∑ni∑mjgcd(i,j)k mod 109+7
题解:
先上经典的莫比乌斯反演变形得到:
∑min(n,m)d=1dk∑min(⌊nd⌋,⌊md⌋)p=1μ(p)⌊ndp⌋⌊mdp⌋
=∑min(n,m)T=1⌊nT⌋⌊mT⌋∑d|Tddk∗μ(Td)
设f(T)= ∑dd|Tdk∗μ(Td)
关键要求f的前缀和。
orz
ps:注意int,long long 的转换
code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
LL prime[5000010],f[5000010],p[5000010];
int pr,k;
bool v[5000010];
const LL mod=1000000007;
LL work(LL a,int b)
{
LL ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;b>>=1;
}
return ans;
}
void pre()
{
memset(v,true,sizeof(v));
pr=0;f[1]=1;
for(int i=2;i<=5000000;i++)
{
if(v[i])
{
prime[++pr]=(LL)i;
f[i]=(work(i,k)-1)%mod;
}
for(int j=1;j<=pr&&(LL)i*prime[j]<=5000000;j++)
{
v[i*prime[j]]=false;
if(i%prime[j]==0){f[i*prime[j]]=(f[i]*work(prime[j],k))%mod;break;}
f[i*prime[j]]=(f[i]*f[prime[j]])%mod;
}
}
for(int i=2;i<=5000000;i++) f[i]=(f[i]+f[i-1])%mod;
}
int main()
{
int T;scanf("%d %d",&T,&k);
pre();
while(T--)
{
int n,m;scanf("%d %d",&n,&m);
LL ans=0;int j;
if(n>m) swap(n,m);
for(int i=1;i<=n;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans=(ans+(LL)(n/i)*(LL)(m/i)%mod*((f[j]-f[i-1]+mod)%mod)%mod)%mod;
}
printf("%lld\n",(ans+mod)%mod);
}
}