一、题面
样例输入:
2
5 8
样例输出:
8
14
二、思路
关键词:线性筛
在Zed的帮助下知道了这是一道线性筛的比较裸的题了。考试过程中肝这道题的时间最久,费了心思找到递推式后,发现根本不是在1s内能实现的东西。考试过程中大三学长选择了暴力打表打了几十KB。。。考后向Zed请教良久知道了线性筛。线性筛最基础的作用是筛出所有质数,时间复杂度仅为o(n)。由于f(x)是“积性函数”(f(a * b) = f(a) * f(b)),所以也可以用线性筛处理。
三、代码
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std; #define MAXN 200005
#define MAXT 25 int T, a[MAXT], n, tot, g[MAXN], p[MAXN], s[MAXN], f[MAXN], v[MAXN]; void work() {
f[] = , s[] = ;
for (int i = ; i <= n; i++) {
if (!v[i]) p[++tot] = i, f[i] = ;
for (int j = ; j <= tot; j++) {
int k = i * p[j];
if (k > n) break;
v[k] = ;
if (!(i % p[j])) {
f[k] = g[i] ? : f[i] / ;
g[k] = ;
break;
}
else f[k] = f[i] * ;
}
s[i] = s[i - ] + f[i];
}
} int main() {
scanf("%d", &T);
for (int i = ; i <= T; i++) scanf("%d", &a[i]), n = max(a[i], n);
work();
for (int i = ; i <= T; i++) printf("%d\n", s[a[i]]);
return ;
}