1. 程式人生 > >HDU - 5942 :Just a Math Problem (莫比烏斯)

HDU - 5942 :Just a Math Problem (莫比烏斯)

題意:略。

思路:問題轉化為1到N,他們的滿足mu[d]!=0的因子d個數。  即1到N的因子的莫比烏斯係數平方和。

(經驗:累加符號是累加的個數,我們把常數提到前面,然後用杜教篩累加個數即可。

https://www.cnblogs.com/clrs97/p/6012285.html

關鍵部分,perfectxx都給了註釋的(感謝)

 

http://www.perfectxxlowiq.com/2018/03/22/hdu5942-%E6%95%B0%E8%AE%BA/

#include<bits/stdc++.h>
#define ll long long
using
namespace std; const int maxn=1000010; const int Mod=1e9+7; int mu[maxn],p[maxn],vis[maxn],cnt,f[maxn]; void pre() { mu[1]=1; for(int i=2;i<maxn;i++){ if(!vis[i]) p[++cnt]=i,mu[i]=-1; for(int j=1;j<=cnt&&i*p[j]<maxn;j++){ vis[i*p[j]]=1;
if(i%p[j]) mu[i*p[j]]=-mu[i]; else break; } } } int F(ll x) { if(x<maxn&&f[x]) return f[x]; ll res=0; for(ll i=1,j;i<=x;i=j+1){ j=x/(x/i); res+=(j-i+1)*(x/i); } res%=Mod; if(x<maxn) f[x]=res; return res; } int main() { pre();
int T,C=0; ll N; int ans; scanf("%d",&T); while(T--){ scanf("%lld",&N); ans=0; for(int i=1;i<=N/i;i++){ if(mu[i]) ans=(ans+F(N/i/i)*mu[i])%Mod; } printf("Case #%d: %d\n",++C,(ans+Mod)%Mod); } return 0; }