1. 程式人生 > >bzoj4916 神犇和蒟蒻

bzoj4916 神犇和蒟蒻

eight height pos line cnblogs map register mat pow

Description

很久很久以前,有一只神犇叫yzy; 很久很久之後,有一只蒟蒻叫lty;

Input

請你讀入一個整數N;1<=N<=1E9,A、B模1E9+7;

Output

請你輸出一個整數A=\sum_{i=1}^N{\mu (i^2)}; 請你輸出一個整數B=\sum_{i=1}^N{\varphi (i^2)};

技術分享

Sample Input

1

Sample Output

1
1

正解:杜教篩。

第一問答案是$1$。

第二問,先給個結論:$\varphi (n^{2})=n\varphi (n)$,於是我們要求$F(n)=\sum_{i=1}^{n}i\varphi (i)$。

設$f(n)=n\varphi (n)$,考慮$f$與$id$函數的狄利克雷卷積,$id*f(n)=\sum_{d|n}id(d)f(\frac{n}{d})$

$id*f(n)=n\sum_{d|n}\varphi (\frac{n}{d})=n^{2}$,那麽$\sum_{i=1}^{n}id*f(i)=\frac{n(n+1)(2n+1)}{6}$

又$\sum_{i=1}^{n}id*f(i)=\sum_{i=1}^{n}\sum_{d|n}id(d)f(\frac{n}{d})=\sum_{ij\leq n}id(i)f(j)=\sum_{i=1}^{n}id(i)F(\left \lfloor \frac{n}{i} \right \rfloor)$

於是$F(n)=id(1)F(n)=\sum_{i=1}^{n}id*f(i)-\sum_{i=2}^{n}id(i)F(\left \lfloor \frac{n}{i} \right \rfloor)=\frac{n(n+1)(2n+1)}{6}-\sum_{i=2}^{n}id(i)F(\left \lfloor \frac{n}{i} \right \rfloor)$

然後直接用杜教篩的套路:數論分塊+記憶化搜索就行了。

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4
#include <cstring> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #define rhl (1000000007) 14 #define N (3000010) 15 #define inf (1<<30) 16 #define il inline 17 #define RG register 18 #define ll long long 19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 20 21 using namespace std; 22 23 int vis[N],phi[N],prime[N],n,maxn,cnt; 24 ll f[N],In2,In6; 25 26 map <ll,ll> F,vi; 27 28 il int gi(){ 29 RG int x=0,q=1; RG char ch=getchar(); 30 while ((ch<0 || ch>9) && ch!=-) ch=getchar(); 31 if (ch==-) q=-1,ch=getchar(); 32 while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar(); 33 return q*x; 34 } 35 36 il ll qpow(RG ll a,RG ll b){ 37 RG ll ans=1; 38 while (b){ 39 if (b&1) ans=ans*a%rhl; 40 a=a*a%rhl,b>>=1; 41 } 42 return ans; 43 } 44 45 il void sieve(){ 46 phi[1]=f[1]=1; 47 for (RG int i=2;i<=maxn;++i){ 48 if (!vis[i]) prime[++cnt]=i,phi[i]=i-1; 49 for (RG int j=1,k;j<=cnt;++j){ 50 k=i*prime[j]; if (k>maxn) break; vis[k]=1; 51 if (i%prime[j]) phi[k]=phi[i]*phi[prime[j]]; 52 else{ phi[k]=phi[i]*prime[j]; break; } 53 } 54 } 55 for (RG int i=2;i<=maxn;++i) f[i]=(f[i-1]+(ll)i*(ll)phi[i])%rhl; return; 56 } 57 58 il ll du(RG ll n){ 59 if (n<=maxn) return f[n]; if (vi[n]) return F[n]; 60 RG ll ans=n*(n+1)%rhl*(2*n+1)%rhl*In6%rhl,pos; vi[n]=1; 61 for (RG ll i=2;i<=n;i=pos+1){ 62 pos=n/(n/i); 63 ans-=(i+pos)*(pos-i+1)%rhl*du(n/i)%rhl*In2%rhl; 64 if (ans<0) ans+=rhl; 65 } 66 return F[n]=ans; 67 } 68 69 il void work(){ 70 n=gi(),puts("1"),maxn=min(3000000,n),sieve(); 71 In2=qpow(2,rhl-2),In6=qpow(6,rhl-2); 72 printf("%lld\n",du(n)); return; 73 } 74 75 int main(){ 76 File("phi"); 77 work(); 78 return 0; 79 }

bzoj4916 神犇和蒟蒻