今天可爱的Mayuyu带大家来学习线性筛选,以及分析它的时间复杂度。。。
首先,我们学过素数筛选,它也叫线性筛选,因为对于每一个数,我们只需要把它的倍数筛去就行了,这样以及筛出
的就不再继续判断,Mayuyu写的的素数筛选代码如下:
void isprime()
{
cnt = 0;
memset(prime,true,sizeof(prime));
for(int i=2; i<N; i++)
{
if(prime[i])
{
p[cnt++] = i;
for(int j=i+i; j<N; j+=i)
prime[j] = false;
}
}
}
嗯,这样Mayuyu认为比较完美了。。。
现在我们先来看一个题。
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1215
分析:嗯,本题T比较大,所以如果暴力肯定会TLE,那么就当然想到了预处理。怎么预处理呢? 这当然难不倒聪
明的Mayuyu,我们这样想,对于每一个数它一定是它的所有因子的倍数,那么我们就可以像素数筛选那样
去做了,很快Mayuyu写出了代码。。。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 500005;
int sum[N];
void Init()
{
memset(sum,0,sizeof(sum));
for(int i=1; i<N; i++)
{
for(int j=i; j<N; j+=i)
sum[j] += i;
sum[i] -= i;
}
}
int main()
{
Init();
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("%d\n",sum[n]);
}
return 0;
}
嗯,完美解出上题后我们继续来分析时间复杂度。。。
从循环语句可以看出,循环次数为,Mayuyu知道结论:
,现在来证明它。
证明:
所以进一步得到
证明完毕!