BZOJ 4407 于神之怒加强版
http://www.lydsy.com/JudgeOnline/problem.php?id=4407
题意:
给下N,M,K.求
思路:
来自:http://blog.csdn.net/ws_yzy/article/details/50670213
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #define ll long long const ll Mod=1000000007; ll f[5000005],sum[5000005],p[5000005],s[5000005]; bool mark[5000005]; ll K,n,m; ll read(){ ll t=0,f=1;char ch=getchar(); while (ch<'0'||'9'<ch){if (ch=='-') f=-1;ch=getchar();} while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f; } ll Pow(ll x,ll y){ ll res=1; while (y){ if (y%2) res=(res*x)%Mod; y/=2; x=(x*x)%Mod; } return res; } void init(){ f[1]=1; for (int i=2;i<=5000000;i++){ if (!mark[i]){ p[++p[0]]=i; s[p[0]]=Pow(i,K); f[i]=s[p[0]]-1; } for (int j=1;j<=p[0]&&p[j]*i<=5000000;j++){ mark[p[j]*i]=1; if (i%p[j]==0){ f[i*p[j]]=f[i]*s[j]%Mod; break; } f[i*p[j]]=f[i]*f[p[j]]%Mod; } } for (int i=1;i<=5000000;i++) sum[i]=sum[i-1]+f[i]%Mod; } int main(){ int T=read();K=read(); init(); while (T--){ n=read();m=read(); if (n>m) std::swap(n,m); int j=1; ll ans=0; for (int i=1;i<=n;i=j+1){ j=std::min(n/(n/i),m/(m/i)); ans+=(((n/i)*(m/i)%Mod)*(sum[j]-sum[i-1]))%Mod; ans%=Mod; } printf("%lld\n",ans); } return 0; }