最近刚看莫比乌斯反演 数学不好是硬伤啊 不过总算跑出来了
第一种是没优化的跑这题
#include
#include
using namespace std;
const int maxn = 1e7 + 5;
int isprime[maxn];
int prime[maxn];
int mu[maxn];
int cnt;
void mobi(int n)
{
memset(isprime, 0, sizeof isprime);
mu[1] = 1;
cnt = 0;
for(int i = 2; i <= n; i++)
{
if(!isprime[i]){
prime[cnt++] = i;
mu[i] = -1;
}
for(int j = 0; j < cnt && i * prime[j] <= n; j++)
{
isprime[i * prime[j]] = 1;
if(i % prime[j]) mu[i * prime[j]] = -mu[i];
else{
mu[i * prime[j]] = 0;
break;
}
}
}
}
int main()
{
int a;
long long ans = 0;
cin>>a;
mobi(a);
for(int j = 0; j < cnt && prime[j] <= a; j++)
{
long long tmp = a / prime[j];
for(int i = 1; i <= tmp; i++)
ans += 1ll * mu[i] * ((tmp/i) * (tmp/i));
}
cout<
第二种是优化过
#include
#include
using namespace std;
const int maxn = 1e7 + 5;
int isprime[maxn];
int prime[maxn];
int g[maxn];
int sum[maxn];
int mu[maxn];
int cnt;
void mobi(int n)
{
memset(isprime, 0, sizeof isprime);
memset(g, 0, sizeof g);
mu[1] = 1;
cnt = 0;
for(int i = 2; i <= n; i++)
{
if(!isprime[i]){
prime[cnt++] = i;
mu[i] = -1;
g[i] = 1;
}
for(int j = 0; j < cnt && i * prime[j] <= n; j++)
{
isprime[i * prime[j]] = 1;
if(i % prime[j])
{
mu[i * prime[j]] = -mu[i];
g[i * prime[j]] = mu[i] - g[i];
}
else{
mu[i * prime[j]] = 0;
g[i * prime[j]] = mu[i];
break;
}
}
}
sum[0] = 0;
for(int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + g[i];
}
int main()
{
int a;
long long ans = 0;
cin>>a;
mobi(a);
for(int i = 1, last; i <= a; i = last + 1)
{
last = a/(a/i);
ans += (long long)(sum[last] - sum[i - 1]) * (a/i) * (a/i);
}
cout<