很好的入门讲解
51nod1244和51nod1239是求mu和求phi,略
//get mu
#include
#include
#include
#include
#include
#define N 6366666
#define lint long long
#define debug(x) cerr<<#x<<"="<
#define sp <<" "
#define ln <
using namespace std;
unordered_map sav;
bool np[N];lint ps[N];
int pri[N],f[N],fs[N];
inline int prelude(int n)
{
f[1]=fs[1]=1;
for(int i=2,c=0,x;i<=n;++i)
{
if(!np[i]) pri[++c]=i,f[i]=-1;fs[i]=fs[i-1]+f[i];
for(int j=1;j<=c&&(lint)i*pri[j]<=n;++j)
{
x=i*pri[j],np[x]=true;
if(i%pri[j]) f[x]=-f[i];
else { f[x]=0;break; }
}
}
return 0;
}
inline lint G(lint n)
{
return 1+n-n;
}
lint F(lint n)
{
if(sav.count(n)) return sav[n];
if(nreturn fs[n];lint ans=0ll;
for(lint s=2,t;s<=n;s=++t) t=n/(n/s),ans+=(t-s+1)*F(n/t);
return sav[n]=G(n)-ans;
}
int main()
{
prelude(N-1);
lint a,b;scanf("%lld%lld",&a,&b);
return !printf("%lld\n",F(b)-F(a-1));
}
//get phi
#include
#include
#include
#include
#include
#define N 6000000
#define lint long long
#define debug(x) cerr<<#x<<"="<
#define sp <<" "
#define ln <
#define mod 1000000007
#define inv2 500000004
using namespace std;
unordered_mapint > sav;
bool np[N];lint ps[N];
int pri[N],f[N],fs[N];
inline int prelude(int n)
{
fs[1]=f[1]=1;
for(int i=2,c=0,x;i<=n;++i)
{
if(!np[i]) pri[++c]=i,f[i]=i-1;
fs[i]=fs[i-1]+f[i],fs[i]%=mod;
for(int j=1;j<=c&&(lint)i*pri[j]<=n;++j)
{
x=i*pri[j],np[x]=true;
if(i%pri[j]) f[x]=f[i]*f[pri[j]];
else { f[x]=f[i]*pri[j];break; }
}
}
return 0;
}
inline lint G(lint n)
{
return n*inv2%mod*(n+1)%mod;
}
int F(lint n)
{
if(sav.count(n)) return sav[n];
if(nreturn fs[n];lint ans=0ll;
for(lint s=2,t;s<=n;s=++t) t=n/(n/s),ans+=(t-s+1ll)%mod*F(n/t)%mod;
return sav[n]=(G(n%mod)-ans%mod+mod)%mod;
}
int main()
{
prelude(N-1);lint n;scanf("%lld",&n);
return !printf("%d\n",F(n));
}
51nod1227那个链接也有讲,然后有两个技巧分别是,小于等于n的和n互质的数字的和,等于(n*phi(n)+[n==1])/2;以及杜教筛的时候并不对d*phi(d)做替换,而只对phi(d)做替换。
#include
#include
#include
#include
#include
#define N 6000000
#define lint long long
#define debug(x) cerr<<#x<<"="<
#define sp <<" "
#define ln <
#define mod 1000000007
#define inv2 500000004
#define inv6 166666668
using namespace std;
unordered_map<int,int> sav;
bool np[N];
int pri[N],f[N],fs[N];
inline int mol(lint x) { return x%=mod,x<0?x+mod:x; }
inline int prelude(int n)
{
fs[1]=f[1]=1;
for(int i=2,c=0,x;i<=n;++i)
{
if(!np[i]) pri[++c]=i,f[i]=i-1;
fs[i]=(fs[i-1]+(lint)f[i]*i)%mod;
for(int j=1;j<=c&&(lint)i*pri[j]<=n;++j)
{
x=i*pri[j],np[x]=true;
if(i%pri[j]) f[x]=f[i]*f[pri[j]];
else { f[x]=f[i]*pri[j];break; }
}
}
//for(int i=1;i<=30;i++) debug(i)sp,debug(f[i])ln;
return 0;
}
inline int G(int n) { return n*(n+1ll)%mod*(2*n+1ll)%mod*inv6%mod; }
inline int H(int a,int b) { return (a+b)*(b-a+1ll)%mod*inv2%mod; }
int F(int n)
{
if(nreturn fs[n];lint ans=0ll;if(sav.count(n)) return sav[n];
for(int s=2,t;s<=n;s=++t) t=n/(n/s),ans+=(lint)H(s,t)*F(n/t)%mod;
return sav[n]=mol(G(n)-ans);
}
inline int S(int n,lint ans=0ll)
{
for(int s=1,t;s<=n;s=++t)
t=n/(n/s),ans+=(lint)mol(F(t)-F(s-1))*(n/t)%mod;
return (ans+n)%mod*inv2%mod;
}
int main()
{
prelude(N-1);int a,b;scanf("%d%d",&a,&b);
return printf("%d\n",mol(S(b)-S(a-1))),0;
}
51nod 1237注意到i和j都是到n的,不要用莫比乌斯函数作反演而直接上phi会比较方便。
#include
#include
#include
#include
#include
#include
#define A(x) assert(x>=0)
#define N 6000000
#define lint long long
#define debug(x) cerr<<#x<<"="<
#define sp <<" "
#define ln <
#define mod 1000000007
#define inv2 500000004
#define inv6 166666668
using namespace std;
unordered_mapint > sav;
bool np[N];int pri[N],f[N],fs[N];
inline int mol(lint x) { return x%=mod,x<0?x+mod:x; }
inline int prelude(int n)
{
fs[1]=f[1]=1;
for(int i=2,c=0,x;i<=n;++i)
{
if(!np[i]) pri[++c]=i,f[i]=i-1;
fs[i]=(fs[i-1]+f[i])%mod;
for(int j=1;j<=c&&(lint)i*pri[j]<=n;++j)
{
x=i*pri[j],np[x]=true;
if(i%pri[j]) f[x]=f[i]*f[pri[j]];
else { f[x]=f[i]*pri[j];break; }
}
}
//for(int i=1;i<=30;i++) debug(i)sp,debug(f[i])ln;
return 0;
}
inline int H(lint a,lint b) { return (a+b)%mod*(b-a+1)%mod*inv2%mod; }
inline int G(lint n) { return H(1ll,n); }
int F(lint n)
{
if(nreturn fs[n];lint ans=0ll;if(sav.count(n)) return sav[n];
for(lint s=2,t;s<=n;s=++t) t=n/(n/s),ans+=(t-s+1)%mod*F(n/t)%mod;
return sav[n]=mol(G(n%mod)-ans);
}
int main()
{
prelude(N-1);lint n;scanf("%lld",&n);lint ans=0;
for(lint s=1,t;s<=n;s=++t) t=n/(n/s),ans+=(lint)H(s,t)*F(n/t)%mod;
return !printf("%d\n",mol(ans*2-G(n%mod)));
}
51nod 1238几乎和51nod1227一模一样,略。
#include
#include
#include
#include
#include
#include
#define A(x) assert(x>=0)
#define N 6000000
#define lint long long
#define debug(x) cerr<<#x<<"="<
#define sp <<" "
#define ln <
#define mod 1000000007
#define inv2 500000004
#define inv6 166666668
using namespace std;
unordered_mapint > sav;
bool np[N];int pri[N],f[N],fs[N];
inline int mol(lint x) { return x%=mod,x<0?x+mod:x; }
inline int prelude(int n)
{
fs[1]=f[1]=1;
for(int i=2,c=0,x;i<=n;++i)
{
if(!np[i]) pri[++c]=i,f[i]=i-1;
fs[i]=(fs[i-1]+(lint)f[i]*i%mod*i)%mod;
for(int j=1;j<=c&&(lint)i*pri[j]<=n;++j)
{
x=i*pri[j],np[x]=true;
if(i%pri[j]) f[x]=f[i]*f[pri[j]];
else { f[x]=f[i]*pri[j];break; }
}
}
//for(int i=1;i<=30;i++) debug(i)sp,debug(f[i])ln;
return 0;
}
inline int F(lint a,lint b) { return (a+b)%mod*(b-a+1)%mod*inv2%mod; }
inline int G(lint n) { return n%=mod,n*(n+1)%mod*(2*n+1)%mod*inv6%mod; }
inline int G(lint a,lint b) { return mol(G(b)-G(a-1)); }
inline int H(lint n) { return (lint)F(1,n)*F(1,n)%mod; }
inline int H(lint a,lint b) { return mol(H(b)-H(a-1)); }
int S(lint n)
{
if(nreturn fs[n];lint ans=0ll;if(sav.count(n)) return sav[n];
for(lint s=2,t;s<=n;s=++t) t=n/(n/s),ans+=(lint)G(s,t)*S(n/t)%mod;
return sav[n]=mol(H(n%mod)-ans);
}
int main()
{
prelude(N-1);lint n;scanf("%lld",&n);lint ans=0;
for(lint s=1,t;s<=n;s=++t) t=n/(n/s),ans+=(lint)F(s,t)*S(n/t)%mod;
return !printf("%lld\n",ans%mod);
}