的做法求出来,但是有点爆啊所以这里采取枚举j的做法,
有g[j]=1,g[j+1,j∗2]=2,g[j∗2+1,j∗3]=3,...,g[j∗k+1,n]=k+1
转化一下,就是
g[j,n]+=1,g[j+1,n]+=1,g[j∗2+1,n]+=1,...,g[j∗k+1,n]+=1
所以在每个+1开始的位置加上1,然后前缀和处理一下就行了
我这里写的麻烦了,其实不用把mu[]求出来,直接计算就行.
附本题代码
———————————————————————————————————————————
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| int n; LL g[N],f[N]; int mu[N],prime[N],vis[N],cnt; void Init() { memset(vis,0,sizeof(vis)); mu[1] = 1; cnt = 0; for(int i=2; i<N; i++) { if(!vis[i]) { prime[cnt++] = i; mu[i] = -1; } for(int j=0; j<cnt&&i*prime[j]<N; j++) { vis[i*prime[j]] = 1; if(i%prime[j]) mu[i*prime[j]] = -mu[i]; else { mu[i*prime[j]] = 0; break; } } } }
int main(){ Init(); for(int i=1;i<N;i++){ g[i]++; for(int j=i;j<N;j+=i) g[j+1]++; } for(int i=1;i<N;i++) g[i]+=g[i-1];
for(int i=1;i<N;i++) for(int j=i;j<N;j+=i) f[j]=(f[j]+mu[i]*g[j/i])%MOD;
for(int i=1;i<N;i++) f[i]=(f[i]+f[i-1])%MOD;
while(~scanf("%d",&n)) printf("%lld\n",f[n]);
return 0; }
|
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 tabris的博客! 赞助
wechat
alipay