[文章目录]
Description
多组数据,所有数据的k相同,1<=N,M,K<=5000000,1<=T<=2000 求
推式子!!!
=
=
=
把k*d提前枚举 (注: 的d和k等价于 的p和d/p)
=
诶??辣不是狄利克雷卷积吗?还都是积性函数,直接快筛+分块
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod=1000000007ll;
ll k,n,m;
ll ans[5001000],po[5001000];
ll pri[5001000],cnt;
bool v[5001000];
ll pow(ll x,ll y)
{
ll re=1;
while(y)
{
if(y&1) re=re*x%mod;
x=x*x%mod; y>>=1;
}
return re;
}
void quick_ans()
{
ans[1]=1; po[1]=1;
for(ll i=2;i<=5000000;++i)
{
if(!v[i])
{
pri[++cnt]=i; po[cnt]=pow(i,k);
ans[i]=(po[cnt]+mod-1)%mod;
}
for(ll j=1;i*pri[j]<=5000000&&j<=cnt;++j)
{
v[i*pri[j]]=1;
if(i%pri[j]) ans[i*pri[j]]=ans[i]*ans[pri[j]]%mod;
else
{
ans[i*pri[j]]=ans[i]*po[j]%mod;
break;
}
}
}
for(ll i=1;i<=5000000;++i) ans[i]=(ans[i]+ans[i-1])%mod;
}
int main()
{
int t; scanf("%d%lld",&t,&k);
quick_ans();
while(t--)
{
scanf("%lld%lld",&n,&m); if(n>m) swap(n,m);
ll b=1,e,fna=0;
while(b<=n)
{
e=min(n/(n/b),m/(m/b));
fna=(fna+(ans[e]-ans[b-1]+mod)%mod*(n/b)%mod*(m/b)%mod)%mod;
b=e+1;
}
printf("%lld\n",fna);
}
return 0;
}