BZOJ 4916 神犇和蒟蒻
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
第一问很好笑,众所周知,μ(i*j)如果gcd(i,j)!=1,那么μ(i*j)就是0
也就是说,第一问无论n多大就是1
第二问可以转化为$\sum_{i=1}^ni*\phi(i)$
这是从定义式推来的
令
$f[n]=n*\phi(n)$
$S[n]=\sum_{i=1}^ni*\phi(i)$
然后就是杜教筛
$g(1)S(n)=\sum_{i=1}^n(f*g)(i)-\sum_{i=2}^ng(i)S(\frac{n}{i})$
$\sum_{i=1}^n(f*g)(i)$
$=\sum_{i=1}^n\sum_{d|i}f(\frac{i}{d})g(d)$
$=\sum_{i=1}^n\sum_{d|i}\frac{i}{d}\phi(\frac{i}{d})g(d)$
$=\sum_{i=1}^n\sum_{d|i}f(\frac{i}{d})g(d)$
$=\sum_{i=1}^n\sum_{d|i}\frac{i}{d}\phi(\frac{i}{d})g(d)$
因为$\sum_{d|i}\phi(d)=i$
所以令g(x)=x
$=\sum_{i=1}^n{i}\sum_{d|i}\phi(\frac{i}{d})$
$=\sum_{i=1}^ni^2$
所以令g(x)=x
$=\sum_{i=1}^n{i}\sum_{d|i}\phi(\frac{i}{d})$
$=\sum_{i=1}^ni^2$
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<map> 7 using namespace std; 8 typedef long long lol; 9 int N=8000000,Mod=1e9+7,inv6; 10 int prime[1000001],phi[8000000+5],n,tot; 11 bool vis[8000000+5]; 12 map<int,int> M; 13 int qpow(int x,int y) 14 { 15 int res=1; 16 while (y) 17 { 18 if (y&1) res=1ll*res*x%Mod; 19 x=1ll*x*x%Mod; 20 y>>=1; 21 } 22 return res; 23 } 24 int query(int x) 25 {int i,pos; 26 if (x<=N) return phi[x]; 27 if (M[x]) return M[x]; 28 int as=1ll*(x+1)*x%Mod*(2*x+1)%Mod*inv6%Mod; 29 for (i=2;i<=x;i=pos+1) 30 { 31 pos=x/(x/i); 32 as-=(1ll*(pos+i)*(pos-i+1)/2)%Mod*query(x/i)%Mod; 33 as=(as+Mod)%Mod; 34 } 35 return M[x]=as; 36 } 37 void pre() 38 {int i,j; 39 phi[1]=1; 40 for (i=2;i<=N;i++) 41 { 42 if (vis[i]==0) 43 { 44 prime[++tot]=i; 45 phi[i]=i-1; 46 } 47 for (j=1;j<=tot;j++) 48 { 49 if (1ll*i*prime[j]>N) break; 50 vis[i*prime[j]]=1; 51 if (i%prime[j]==0) 52 { 53 phi[i*prime[j]]=1ll*phi[i]*prime[j]%Mod; 54 break; 55 } 56 else phi[i*prime[j]]=1ll*phi[i]*(prime[j]-1)%Mod; 57 } 58 } 59 for (i=1;i<=N;i++) 60 { 61 phi[i]=(1ll*i*phi[i]%Mod+phi[i-1])%Mod; 62 } 63 } 64 int main() 65 { 66 cin>>n; 67 cout<<1<<endl; 68 N=min(N,n); 69 pre(); 70 inv6=qpow(6,Mod-2); 71 printf("%d\n",query(n)); 72 }