3561: DZY Loves Math VI
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 503 Solved: 333
[Submit][Status][Discuss]
Description
给定正整数n,m。求
Input
一行两个整数n,m。
Output
一个整数,为答案模1000000007后的值。
Sample Input
5 4
Sample Output
424
HINT
数据规模:
1<=n,m<=500000,共有3组数据。
Source
莫比乌斯反演
http://blog.csdn.net/lych_cys/article/details/50721642?locationNum=1&fps=1
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define mod 1000000007 4 #define N 500001 5 using namespace std; 6 int n,m,cnt,mo[N],p[N>>1],vis[N];ll a[N],sum[N],ans; 7 void predeal(){ 8 mo[1]=1; 9 for(int i=2;i<N;i++){ 10 if(!vis[i]){mo[i]=-1;p[++cnt]=i;} 11 for(int j=1;j<=cnt&&i*p[j]<N;++j){ 12 vis[i*p[j]]=1; 13 if(i%p[j])mo[i*p[j]]=-mo[i]; 14 else{mo[i*p[j]]=0;break;} 15 } 16 } 17 } 18 int quick(int a,int b){ 19 int ret=1; 20 while(b){ 21 if(b&1)ret=1ll*a*ret%mod; 22 a=1ll*a*a%mod;b>>=1; 23 } 24 return ret; 25 } 26 int main(){ 27 scanf("%d%d",&n,&m);predeal();if(n>m)swap(n,m); 28 for(int i=1;i<N;i++)a[i]=1; 29 for(int i=1;i<=n;i++){ 30 ll res=0; 31 for(int j=1;j*i<=m;++j) 32 a[j]=a[j]*j%mod,sum[j]=(sum[j-1]+a[j])%mod; 33 for(int j=1;j*i<=n;++j) 34 if(mo[j])res=(res+mo[j]*a[j]*a[j]%mod*sum[n/i/j]%mod*sum[m/i/j]%mod)%mod; 35 ans=(ans+res*quick(i,i)%mod)%mod; 36 } 37 ans<0?ans+=mod:1;printf("%lld\n",ans); 38 return 0; 39 }