这题正常多了。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 5000050 #define mod 1000000007 using namespace std; long long t,n,m,k,prime[maxn],tot=0,k1[maxn],k2[maxn],tab[maxn]; bool vis[maxn]; long long f_pow(long long x,long long y) { long long base=x,ans=1; while (y) { if (y&1) ans=(ans*base)%mod; base=(base*base)%mod; y>>=1; } return ans; } void get_table() { k1[1]=k2[1]=1; for (long long i=2;i<=maxn-50;i++) { if (!vis[i]) { tab[i]=f_pow(i,k); k1[i]=(tab[i]+mod-1)%mod;k2[i]=1; prime[++tot]=i; } for (long long j=1;j<=tot && i*prime[j]<=maxn-50;j++) { vis[i*prime[j]]=true; if (i%prime[j]) { k1[i*prime[j]]=(tab[prime[j]]+mod-1)%mod; k2[i*prime[j]]=k1[i]*k2[i]%mod; continue; } k1[i*prime[j]]=k1[i]*tab[prime[j]]%mod; k2[i*prime[j]]=k2[i];break; } } for (long long i=1;i<=maxn-50;i++) {k1[i]=(k1[i]*k2[i])%mod;k1[i]=(k1[i-1]+k1[i])%mod;} } int main() { scanf("%lld%lld",&t,&k);get_table(); for (long long i=1;i<=t;i++) { scanf("%lld%lld",&n,&m); if (n>m) swap(n,m); long long ans=0,l=1,r; while (l<=n) { r=min(n/(n/l),m/(m/l)); ans=(ans+(n/l)*(m/l)%mod*((k1[r]-k1[l-1]+mod)%mod))%mod; l=r+1; } printf("%lld ",ans); } return 0; }