您的位置:首页 > 其它

[杜教筛] BZOJ3512. DZY Loves Math IV

2017-12-22 13:24 357 查看
%%%Vectorxj

http://blog.csdn.net/vectorxj/article/details/78857079

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>

using namespace std;

typedef pair<int,int> par;

const int N=1e6+10,P=1e9+7;

int mu
,p
,phi
,fac
,pre
;

inline void Pre(const int &n){
phi[1]=1; mu[1]=1; fac[1]=1;
for(int i=2;i<=n;i++){
if(!p[i])
p[++*p]=i,phi[i]=i-1,mu[i]=-1,fac[i]=i;
for(int j=1;j<=*p && 1LL*i*p[j]<=n;j++){
p[i*p[j]]=1;
if(i%p[j]){
fac[i*p[j]]=fac[i]*p[j];
phi[i*p[j]]=phi[i]*phi[p[j]];
mu[i*p[j]]=-mu[i];
}
else{
fac[i*p[j]]=fac[i];
phi[i*p[j]]=phi[i]*p[j];
break;
}
}
}
for(int i=1;i<=n;i++) pre[i]=(phi[i]+pre[i-1])%P;
}

map<par,int> M;
map<int,int> S;

int Phi(int n){
if(n<=1000000) return pre
;
if(S.count(n)) return S
;
int ret=1LL*n*(n+1)/2%P;
for(int i=2,j;i<=n;i=j+1){
j=n/(n/i);
ret=(ret-1LL*(j-i+1)*Phi(n/i))%P;
}
return S
=ret;
}

int Sum(int n,int m){
if(!n || !m) return 0;
if(M.count(par(n,m))) return M[par(n,m)];
if(n==1) return Phi(m);
if(m==1) return phi
;
if(!mu
)
return 1LL*n/fac
*Sum(fac
,m)%P;
int ret=0;
for(int i=1;1LL*i*i<=n;i++){
if(n%i) continue;
ret=(ret+1LL*phi[n/i]*Sum(i,m/i))%P;
if(i*i!=n)
ret=(ret+1LL*phi[i]*Sum(n/i,m/(n/i)))%P;
}
return M[par(n,m)]=ret;
}

int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int n,m,ans=0; scanf("%d%d",&n,&m); Pre(1000000);
for(int i=1;i<=n;i++)
ans=(ans+Sum(i,m))%P;
printf("%d\n",(ans+P)%P);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: