算法提升之欧拉筛

今天给大家介绍关于欧拉筛的相关知识内容,对于欧拉筛大家需要先有一个基础的认识与了解。

欧拉筛主要就是来解决当n的范围>1e7时,用这个方法可以将时间复杂度变为o(n),从而不会导致超时。

1.欧拉筛的具体含义

2.

4.欧拉筛与埃氏筛选的区别

题目1:

问题描述

如果一个数 x 是素数,且 ⌊2x​⌋ 也是素数,则称 x 是好数,例如 5,7,11 都是好数。

现在给定你一个正整数 n,有 q组查询,每组查询给出一个区间 [[l,r],1≤l≤r≤n,询问该区间内有多少个好数。

素数:如果一个数的约数只有 1 和本身,则为素数。

输入格式

第一行二个整数 n,q,表示区间上界和查询数。

接下来 q 行,每行一对 [l,r] 表示查询的区间。

输出格式

对于每次查询,输出区间好数的数量。

输入案例:

20 3
1 9
7 20
11 17

输出案例:

2 
2 
1

代码部分:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 1e6+10;
bitset<N> vis;
vector<int> prime;
ll pre[N];

void oula(int n){
    vis[0]=true;
    vis[1]=true;
    for(int i=2;i<=n;i++){
        if(!vis[i]) prime.push_back(i);
        for(int j=0;j<prime.size()&&i*prime[j]<=n;j++){
            vis[i*prime[j]]=true;
            if(i%prime[j]==0) break;
        }
    }
}

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
        
    int n,q;cin>>n>>q;
    oula(n);
    for(int i=1;i<=n;i++){
        pre[i]=pre[i-1]+(!vis[i]&&!vis[i/2]);
    }
    while(q--){
        int l,r;cin>>l>>r;
        cout<<pre[r]-pre[l-1]<<'\n';
    }
}

这道题可以当作欧拉筛的模版题,大家可以记忆理解,同时欧拉筛的题目还有很多变化。

最小质因子之和(Easy Version)

第二题

题目描述

定义 F(i)表示整数 i 的最小质因子。现给定一个正整数 N,请你求出∑2n​F(i)。

输入描述

第 1行为一个整数 T,表示测试数据数量。

接下来的 TT 行每行包含一个正整数 N。

,2≤N≤3×106。

输出描述

输出共 T 行,每行包含一个整数,表示答案。

输入案例:

3
5
10
15

输出案例:

12
28
59

代码部分:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e6 + 9;
vector<bool> prime(N, false);
vector<int> pre(N, 0);
void era(int n)
{
  prime[0] = prime[1] = true;
  for(int i = 2;i <= n;i ++)
  {
    if(!prime[i])
    {
      pre[i] = i;
      for(int j = i * i;j <= n;j += i)
      {
        prime[j] = true;
        if(pre[j] == 0)pre[j] = i;
      }
    }
  }
  for(int i = 2;i <= n;i ++)pre[i] += pre[i - 1];
}
signed main()
{
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  era((int)3e6);
  int t;cin >> t;
  while(t --)
  {
    int n;cin >> n;
    cout << pre[n] << '\n';
  }
  return 0;
}

好了,今天关于欧拉筛的分享就到这里,希望对大家能有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值