原题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3561
DZY Loves Math VI
Description
给定正整数n,m。求
Input
一行两个整数n,m。
Output
一个整数,为答案模1000000007后的值。
Sample Input
5 4
Sample Output
424
HINT
数据规模:
1<=n,m<=500000,共有3组数据。
题解
因为 dd′ d d ′ 后面还跟了一个 id i d 之类的奇奇怪怪的东西,所以用 T T 来替换并无卵用,但是数据范围只有啊,如果直接枚举的话复杂度为 n1+n2+n3+⋯+nn−1+nn≈n ln(n) n 1 + n 2 + n 3 + ⋯ + n n − 1 + n n ≈ n l n ( n ) ,稳了稳了。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=5e5+5,mod=1000000007;
int p[M/3],miu[M],n,m,nd,md,dd;
ll ans,tmp,sum[M],val[M];
bool isp[M];
ll power(ll x,ll p){ll r=1;for(;p;p>>=1,x=x*x%mod)if(p&1)r=r*x%mod;return r;}
void pre()
{
miu[1]=isp[1]=1;
for(int i=2,t;i<M;++i)
{
if(!isp[i])p[++p[0]]=i,miu[i]=-1;
for(int j=1;j<=p[0],i*p[j]<M;++j){isp[i*p[j]]=1;if(i%p[j]==0)break;miu[i*p[j]]=-miu[i];}
}
}
void in(){scanf("%d%d",&n,&m);}
void ac()
{
if(n>m)swap(n,m);pre();
for(int i=1;i<=m;++i)val[i]=1;
for(int i=1,j;i<=n;++i)
{
nd=n/i,md=m/i,tmp=0;
for(j=1;j<=md;++j)val[j]=val[j]*j%mod,sum[j]=(sum[j-1]+val[j])%mod;
for(j=1;j<=nd;++j)(tmp+=miu[j]*val[j]%mod*val[j]%mod*sum[nd/j]%mod*sum[md/j]%mod)%=mod;
(ans+=tmp*power(i,i)%mod)%=mod;
}
printf("%lld",(ans+mod)%mod);
}
int main(){in();ac();}