一点点bitset疑问?

P3383 【模板】线性筛素数

elpsconr @ 2024-05-08 22:32:15

题解看到的,有点不懂,为啥bitset用在欧拉筛上反而比埃氏筛还慢了,也比原来用bool数组慢

#include<bits/stdc++.h>
using namespace std;
const int N=1e8+6;
int n,q,prime[N],cnt;
bitset<N> st;
void iget(int x)
{
  for(int i=2;i*i<=x;++i)
  {
    if(!st[i]) 
    {
        for(int j=i*i;j<=x;j+=i) st[j]=1;
    } 
  }
  for(int i=2;i<=x;++i) 
  {
    if(!st[i]) prime[++cnt]=i;
  }
}
void get(int x)
{
    for(int i=2;i<=x;++i)
    {
        if(!st[i]) prime[++cnt]=i;
        for(int j=1;prime[j]*i<=x&&j<=cnt;++j)
        {
            st[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
}
int main()
{
  cin.tie(0)->sync_with_stdio(0);
  cin>>n>>q;
  iget(n);
  while(q--)
  {
    int k;cin>>k;
    cout<<prime[k]<<endl;
  }
}

by wly09 @ 2024-05-09 00:12:18

@elpsconr 对于你的问题:

  1. 我在洛谷上提交测试,使用欧拉筛时没有bitsetbool 数组慢的情况”,相反,总时间 bitsetbool 数组快 0.05s\sim 0.10s(bitset 测试、bool 数组测试),因此,bitset 的优化是可以放心使用的;
  2. 关于“欧拉筛比埃氏筛慢”:在算法竞赛中,高复杂度算法在特定数据范围下优于低复杂度算法的情况是较普遍的,我们称之为“常数差异”,对于本题,可能的因素如下:
    • 优化后的埃氏筛的时间复杂度为 O(n\ln\ln\sqrt{n})(渐进仍为 O(n\log\log n),但常数很小),与欧拉筛 O(n) 的复杂度接近,且常数小;
    • 在欧拉筛算法中,需要多次求模运算(耗时大约是乘法运算的 10 倍),导致常数可能偏大;
    • bitset 常数优化确实给力。

by elpsconr @ 2024-05-09 00:20:26

@wly09 感谢,主要还是不理解欧拉筛慢于埃氏筛,受教了


|