bzoj:4407: 于神之怒加强版
Description
给下N,M,K.求
Input
输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意义如上式所示。
Output
如题
Sample Input
1 2
3 3
3 3
Sample Output
20
感觉是道比较水的数论题?
提个d^k随手莫比乌斯反演一下,再把μ跟d^k放在一起,预处理出来就好了。
但是注意预处理的时候写nlogn写法的话会T,要放在线性筛里O(n)筛出来,30+s。
(玛雅,10+s是什么写法
#include<cstdio> #include<algorithm> #define N 5000000 using namespace std; const int MOD=1e9+7; int T,n,m,k,K,num=0,p[N],mu[N+1],ne,f[N+1],mmh; bool bo[N+1]; inline int M(int x) {while (x>=MOD) x-=MOD;while (x<0) x+=MOD;return x;} inline int mi(int a,int x){ mmh=1; while (x){ if (x&1) mmh=1LL*mmh*a%MOD; x>>=1; a=1LL*a*a%MOD; } return mmh; } inline int min(int a,int b){return a<b?a:b;} int main(){ register int i,j,k,l; scanf("%d%d",&T,&K); mu[1]=1;f[1]=1; for (i=2;i<=N;i++){ if (!bo[i]) p[++num]=i,mu[i]=-1,f[i]=mi(i,K)-1; for (j=1;j<=num&&(ne=p[j]*i)<=N;j++){ bo[ne]=1; if (i%p[j]) mu[ne]=-mu[i],f[ne]=1LL*f[i]*f[p[j]]%MOD;else{ mu[ne]=0; f[ne]=1LL*f[i]*mi(p[j],K)%MOD; break; } } } for (i=1;i<=N;i++) f[i]=M(f[i]+f[i-1]); while(T--){ scanf("%d%d",&n,&m); if (n>m) swap(n,m); for (i=1,j=0,mmh=0;i<=n;j=i++) i=min(n/(n/i),m/(m/i)),mmh=M(mmh+1LL*(n/i)*(m/i)%MOD*M(f[i]-f[j])%MOD); printf("%d\n",mmh); } }