bzoj 4916: 神犇和蒟蒻 (杜教筛+莫比乌斯反演)

时间:2021-01-01 09:24:10

题目大意:

  读入n。

  第一行输出“1”(不带引号)。

  第二行输出$\sum_{i=1}^n i\phi(i)$。

题解:

  所以说那个$\sum\mu$是在开玩笑么=。=

  设$f(n)=n\phi(n),F(n)=\sum_{i=1}^{n}f(i)$。

  设$g=(f*id)$,则$g(n)=\sum_{d|n}id(\frac{n}{d})f(d)=n^2$。

  设$G(n)=\sum_{i=1}^n g(i)=\frac{n(n+1)(2n+1)}{6}$。

  同时将$G$完全展开我们得到:

$G(n)=\sum_{i=1}^{n}\sum_{d|i}d*f(\frac{i}{d})$

$=\sum_{d=1}^{n}d\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}f(i)$

$=\sum_{d=1}^{n}dF(\lfloor \frac{n}{d} \rfloor)$

  由此可得:$$F(n)=\frac{n(n+1)(2n+1)}{6}-\sum_{i=2}^{n}F(\lfloor \frac{n}{i} \rfloor)i$$

代码:

 

 #define Troy

 #include <bits/stdc++.h>

 using namespace std;

 inline int read(){
int s=,k=;char ch=getchar();
while(ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while(ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
} const int N=1e6+,mod=1e9+; int phi[N],prim[N],num,vis[N],F[N],f[N],n,re6=,re2=;
map<int,int> mp; inline int calc(int x){
if(x<N) return F[x];
else if(mp.count(x)) return mp[x];
int ret=x*1ll*(x+)%mod*(2ll*x+)%mod*re6%mod;
for(register int i=,j;i<=x;i=j+){
j=x/(x/i);
ret=(ret-(j-i+1ll)*(i+j)/%mod*calc(x/i)%mod)%mod;
if(ret<) ret+=mod;
}
return mp[x]=ret;
} int main(){
n=read();puts("");
register int i,j,k;
phi[]=;
for(i=;i<N;++i){
if(!vis[i]) prim[++num]=i,phi[i]=i-;
for(j=;(k=prim[j]*i)<N;++j){
vis[k]=true;
if(i%prim[j]){
phi[k]=phi[i]*1ll*(prim[j]-)%mod;
continue;
}
phi[k]=phi[i]*1ll*prim[j]%mod;break;
}
}
for(i=;i<N;++i) f[i]=1ll*phi[i]*i%mod,F[i]=(F[i-]*1ll+f[i])%mod;
printf("%d\n",(calc(n)+mod)%mod);
}