数论(第一部分)

本文详细介绍了质数的定义,并探讨了试除法、分解质因数和高效筛选质数的方法,包括时间复杂度优化的线性筛法。重点讲解了如何用O(n)、O(√n)和O(n log n)的时间复杂度求解质数问题,适合ACM竞赛和算法学习者参考。
摘要由CSDN通过智能技术生成

质数

定义
大于等于2的整数中只有1和它本身的因数的数称之为质数(素数)。

选自题目acwing 866 867 868.

试除法求质数:

由定义的方法
时间复杂度o(n)

for (int i = 2;i <= n; i ++)
	if(n%2==0) return ture;
	else return false;

因数都是成对出现的,即i*j=n;i和j都是n的因数。
所以必定存在n>m或者m>n的情况,所以枚举的时候我们从小到大枚举只需要枚举n/i就可以了,最大枚举到根号n的情况。
时间复杂度o(根号n)

for (int i = 2;i <= n/i; i ++)
	if(n%i==0) return false;
return true;

分解质因数

类似的思想,我们同样是从小到大试除
由于所有的合数都是由质数相乘得来的,所以在遍历的时候就可以不用考虑除以合数的情况,依旧从小到大遍厉就可以了
时间复杂度o(根号n)

//计算总数
cin >> n;
s=0;//计数
for(int i = 1; i <= n; i ++)
{
	if(n%i==0)
	{
		// int s = 0;
		while (n%i==0)
		n/=i;
		s++;
		//printf("%d,%d ",i,s);
	}
}
s++;
if(n>1) printf("%d,%d",n,++s);
//每个质因数都计算吧=的情况只需要把s放入第一个if循环内然后输出就可以了

筛质数

还是利用所有合数都可以分解为质数的性质
前P个数中的素数的个数利用筛除,把1~p-1 的范围内的所有的数的倍数都筛除,余下的就都是素数。
时间复杂度约为n(log n)

int primes[N], cnt;     // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (st[i]) continue;
        primes[cnt ++ ] = i;
        for (int j = i + i; j <= n; j += i)
            st[j] = true;
    }
}

但是在数据过大的时候,朴素的筛选法就不太行了,就可以优化成线性筛法
还是利用了之前的两个数相乘,避免了部分数的重复bool赋值

int primes[N], cnt;     // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}
                     南昌理工学院 acm集训队
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值