The sol to Bismuth / Linear Sieve

The sol to Bismuth / Linear Sieve

https://www.luogu.com.cn/problem/P11169

思路

因为懒惰,所以直接转载了当时参考的这篇博客

https://www.luogu.com.cn/article/ys9ualoj

首先观察样例发现第一个样例一定是 \(\lceil \frac{n}{2} \rceil\)

手推一下加入数字的过程:

当处理到数字二时,此时 \(cntp = 1, counter = 1\),并将 \(isnotprime_{4}\) 赋值为 \(1\)

当处理到数字三时,此时 \(cntp = 2, counter = 2\),并将 \(isnotprime_{6}\) 赋值为 \(1\)

......

首先大于所有大于 \(1\) 的奇数而言更新其他数字是否被筛到时,则必然枚举到 \(2\) 就停止了。

接着对于所有大于 \(0\) 的偶数而言更新其他数字是否被筛到时,由于本身是偶数,所以其筛出的数也必然是偶数。

由于两种筛法都没有办法筛出奇数,而 \(n\) 以内大于 \(1\) 的奇数有 \(\lceil \frac{n - 2}{2} \rceil\) 个,接着 \(2\) 一开始没有被筛到,所以 \(cntp\) 一定为 \(\lceil \frac{n - 2}{2} \rceil + 1 = \lceil \frac{n}{2} \rceil\)

接着考虑计算 \(counter\) 的值,对于每个未被筛到的元素单独考虑贡献,假设 \(x\) 为筛倍数时筛到当前考虑的元素中某个 \(i\),当前考虑元素为 \(y\)\(l\) 为未被筛到的元素中小于等于 \(y\)\(\operatorname{lcm}\)

首先必然有 \(x \times y \le n\),那么现在 \(x\) 的范围在 \([1, \lfloor \frac{n}{2} \rfloor]\) 之内,那么 \(x\) 整除 \(l\),由于 \(l\) 增长速度较快,所以需要考虑的元素数量较少,那么只需要考虑这些 \(l \le n\) 中未被筛到的元素。

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
int gcd(int a,int b){
    return __gcd(a,b);
}
int lcm(int a,int b){
    return a/gcd(a,b)*b;
}
signed main(){
    freopen("Bismuth.in","r",stdin);
    freopen("Bismuth.out","w",stdout);
    int n;
    cin>>n;
    if(n==1){
        cout<<"0 0"<<endl;return 0;
    }
    cout<<((n+1)>>1)<<" ";
    int l=2;
    int ans=n/2/2;
    for(int i=2;i<n/2;i++){
        int nw=2*i-1;
        l=lcm(l,nw);
        if(l>n) break;
        ans+=(n/nw)/l;
    }
    cout<<ans<<endl;
    return 0;
}

水完了。

posted @ 2024-11-17 15:04  Qian·JXのjoker  阅读(2)  评论(0编辑  收藏  举报