关于莫比乌斯函数的塞 : 莫比乌斯前n项和 , 莫比乌斯函数绝对值的前n项和
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<map> using namespace std; #define CLR(a,b) memset((a),(b),sizeof((a))) typedef long long ll; const int N = 5000000; bool check[N+10]; int prime[N+10],tot; int mu[N+10]; ll mu_sum[N+10]; void Moblus(){ CLR(check, false); mu[1] = 1; tot = 0; for(int i = 2; i <= N; i++){ if( !check[i] ){ prime[tot++] = i; mu[i] = -1; } for(int j = 0; j < tot && i*prime[j] <= N; j++){ check[i * prime[j]] = true; if( i % prime[j] == 0){ mu[i * prime[j]] = 0; break; } else mu[i * prime[j]] = -mu[i]; } } mu_sum[0]=0; for(int i = 1; i <= N; ++i){ mu_sum[i] = mu_sum[i-1] + mu[i]; } } map<ll,ll> mp; ll Mertens(ll n){ if(n <= N) return mu_sum[n]; if(mp.count(n)) return mp[n]; ll ans = 1, ed; for(ll i = 2; i <= n; i = ed+1){ ed = n/(n/i); ans -= (ed - i + 1)*Mertens(n/i); } return mp[n] = ans; } int main(){ Moblus(); for(int i=1 ; i<=20 ; i++) printf("%d ",mu[i]); int ncase; scanf("%d",&ncase); while(ncase--){ mp.clear(); ll a,k; scanf("%lld%lld", &a, &k); if(k==0){ printf("%lld\n",a); continue; } if(k%2){ printf("%lld\n", Mertens(a) ); continue; } else{ ll ans=0; ll t=sqrt(a); for(int i=1 ; i<= t; i++) { ll T=a/i; T/=i; ans+=mu[i]*T; } printf("%lld\n",ans); } } return 0; }