版权声明:本文为hzy原创文章,未经博主允许不可随意转载。 https://blog.csdn.net/Binary_Heap/article/details/81979908
题意
求 ,
题解
然后可以线性筛 预处理 ,然后通过数论分块 计算答案.
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL;
const int MAXN = 100100;
bool tag[MAXN];
int n, pr[MAXN], cnt, phi[MAXN];
LL phis[MAXN], ans;
void sieve(int n) { //线性筛模版
memset(tag, 1, sizeof tag); tag[1] = false;
phi[1] = phis[1] = 1;
for(int i = 2; i <= n; i ++) {
if(tag[i]) {
pr[++ cnt] = i;
phi[i] = i - 1;
}
for(int j = 1; j <= cnt && i * pr[j] <= n; j ++) {
tag[i * pr[j]] = false;
if(i % pr[j] == 0) {
phi[i * pr[j]] = phi[i] * pr[j];
break ;
}
phi[i * pr[j]] = phi[i] * (pr[j] - 1);
}
phis[i] = phis[i - 1] + phi[i]; //phis为欧拉函数的前缀和.
}
}
int main() {
scanf("%d", &n);
sieve(n);
for(int i = 1, j; i <= n; i = j + 1) {
j = n / (n / i); //j为当前块的右端点,i为左端点
ans += (n / i) * 1ll * (n / i) * (phis[j] - phis[i - 1]);
}
printf("%lld\n", ans);
return 0;
}