[bzoj4916] 神犇和蒟蒻 [杜教篩]

題面:php

傳送門ios

一句話,就是讓你求$\mu\left(i^2\right)$以及$\varphi\left(i^2\right)$的前綴和函數

思路:spa

第一問,瞪了一下子恍然大悟:這不就是1嗎......code

由於對於$\mu\left(i^2\right)$,$i^2=i\ast i$,那麼$\mu\left(i^2\right)$在$i\neq1$的時候值都是0blog

因此第一問輸出1就行了......遞歸

 

接下來看第二問get

這一問中解決$\varphi\left(i^2\right)$是關鍵,由於這東西是個積性函數,能夠套進杜教篩裏面,而一旦進了杜教篩這題就解決了string

當前的關鍵,是找到杜教篩套路式子中的$g\left(x\right)it

我當時想了半天,準備從$\varphi$函數的本質下手,奈何能力不足,就參考了一下某度上的結果,而後看到了這個東西:

發現,當$n$變成$n^2$的時候,右邊的每個質數$p$的指數都上升了$a_p$

也就是說,$\varphi\left(i^2\right)=\varphi\left(i\right)\ast i$

美!滋!滋!

因此咱們只要設$g\left(x\right)=x$,而後套用杜教篩套路:

$ g\left(1\right)S\left(n\right)=\sum_{i=1}^{n}\left(g\ast f\right)\left(i\right)-\sum_{i=2}^{n}g\left(i\right)S\left(\frac ni\right) $

此時g和f函數的卷積等於id

$ S\left(n\right)=\sum_{i=1}^{n}i-\sum{i=2}^{n}iS\left(\frac ni\right) $

而後就遞歸記憶化AC

 

Code:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<map>
 6 #define ll long long
 7 ll MOD=1e9+7,inv6=166666668;  8 using namespace std;  9 inline ll read(){ 10     ll re=0,flag=1;char ch=getchar(); 11     while(ch>'9'||ch<'0'){ 12         if(ch=='-') flag=-1; 13         ch=getchar(); 14  } 15     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar(); 16     return re*flag; 17 } 18 ll tot,pri[2000010],phi[2000010];bool vis[2000010]={0}; 19 void init(){ 20     ll i,j,k;phi[1]=1;vis[1]=1; 21     for(i=2;i<=2000000;i++){ 22         if(!vis[i]){ 23             pri[++tot]=i;phi[i]=i-1; 24  } 25         for(j=1;j<=tot;j++){ 26             k=i*pri[j];if(k>2000000) break; 27             vis[k]=1; 28             if(i%pri[j]==0){ 29                 phi[k]=phi[i]*pri[j]%MOD; 30                 break; 31  } 32             phi[k]=phi[i]*phi[pri[j]]%MOD; 33  } 34  } 35     for(i=1;i<=2000000;i++) phi[i]=(i*phi[i]%MOD+phi[i-1])%MOD; 36 } 37 map<ll,ll>m; 38 ll sum(ll l,ll r){return (r-l+1)*(r+l)/2%MOD%MOD;} 39 ll sum2(ll x){x%=MOD;return x*(x+1)%MOD*(2*x+1)%MOD*inv6%MOD;} 40 ll S(ll x){ 41     if(x<=2000000) return phi[x]; 42     if(m[x]) return m[x]; 43     ll i,j,re=sum2(x); 44     for(i=2;i<=x;i=j+1){ 45         j=x/(x/i); 46         re-=sum(i,j)*S(x/i)%MOD;re%=MOD; 47  } 48     return m[x]=(re+MOD)%MOD; 49 } 50 int main(){ 51  ll i,j,n;init(); 52     n=read();puts("1"); 53     printf("%lld\n",S(n)); 54 }
相關文章
相關標籤/搜索