[ACM][2018南京预赛]Sum

Posted jinkun113

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ACM][2018南京预赛]Sum相关的知识,希望对你有一定的参考价值。

一、题面

技术分享图片

 

样例输入:

2

5 8

样例输出:

8

14

 

二、思路

关键词:线性筛

在Zed的帮助下知道了这是一道线性筛的比较裸的题了。考试过程中肝这道题的时间最久,费了心思找到递推式后,发现根本不是在1s内能实现的东西。考试过程中大三学长选择了暴力打表打了几十KB。。。考后向Zed请教良久知道了线性筛。线性筛最基础的作用是筛出所有质数,时间复杂度仅为o(n)。由于f(x)是“积性函数”(f(a * b) = f(a) * f(b)),所以也可以用线性筛处理。

 

三、代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 #define MAXN 200005
 7 #define MAXT 25
 8 
 9 int T, a[MAXT], n, tot, g[MAXN], p[MAXN], s[MAXN], f[MAXN], v[MAXN];
10 
11 void work() {
12     f[1] = 1, s[1] = 1;
13     for (int i = 2; i <= n; i++) {
14         if (!v[i]) p[++tot] = i, f[i] = 2;
15         for (int j = 1; j <= tot; j++) {
16             int k = i * p[j];
17             if (k > n) break;
18             v[k] = 1;
19             if (!(i % p[j])) {
20                 f[k] = g[i] ? 0 : f[i] / 2;
21                 g[k] = 1;
22                 break;
23             }
24             else f[k] = f[i] * 2;
25         }
26         s[i] = s[i - 1] + f[i];
27     }
28 }
29 
30 int main() {
31     scanf("%d", &T);
32     for (int i = 1; i <= T; i++) scanf("%d", &a[i]), n = max(a[i], n);
33     work();
34     for (int i = 1; i <= T; i++) printf("%d
", s[a[i]]);
35     return 0;
36 }

 

以上是关于[ACM][2018南京预赛]Sum的主要内容,如果未能解决你的问题,请参考以下文章

ACM-ICPC 2018 南京赛区网络预赛 - J. Sum (找规律+打表)

线性素数筛 ACM-ICPC 2018 南京赛区网络预赛 J Sum

ACM-ICPC 2018 南京赛区网络预赛 Magical Girl Haze 最短路

ACM-ICPC 2018 南京赛区网络预赛 E题

ACM-ICPC 2018 南京赛区网络预赛 Lpl and Energy-saving Lamps 线段树

ACM-ICPC 2018 南京赛区网络预赛