loj # 6235. El número de primos de intervalo

El artículo anterior escribió sobre cómo encontrar la suma de números primos de intervalo, y acaba de llegar otro sobre cómo encontrar números primos de intervalo. De hecho, solo se usa la parte del tamiz min25 para encontrar el número primo, y los cambios no son grandes. Para obtener ideas específicas, eche un vistazo a mis notas de estudio del tamiz min25.

#include<bits/stdc++.h>


using namespace std;
typedef long long ll;

const int mod=998244353;

const int maxn = 1e6 + 10;

bool valid[maxn];
ll prime[maxn];
ll sum[maxn];
int tot;
void init()
{
    
    
    tot = 0;
    valid[1] = true;
    for(int i = 2; i < maxn; i++)
    {
    
    
        if(!valid[i])
        {
    
    
            prime[++tot] = i;
            sum[tot] = sum[tot - 1] + ll(1);
        }
        for(int j = 1; j <= tot && i * prime[j] < maxn; j++)
        {
    
    
            valid[i * prime[j]] = true;
            if(i % prime[j] == 0) break;
        }
    }
}

ll id1[maxn], id2[maxn];
ll w[maxn], g[maxn];

ll solve(ll n)
{
    
    
    ll sqr = sqrt(n + 0.5);
    int ntot = 0;
    for(ll i = 1; i <= tot; i++)
    {
    
    
        if(prime[i] <= sqr) ntot++;
        else break;
    }
    int m = 0;
    for(ll i = 1; i <= n; i = n / (n / i) + 1)
    {
    
    
        w[++m] = n / i;
        if(w[m] <= sqr) id1[w[m]] = m;
        else id2[n / w[m]] = m;
        g[m] = w[m] - 1;
    }
    for(int j = 1; j <= ntot; j++)
    {
    
    
        for(int i = 1; i <= m && (ll)prime[j] * (ll)prime[j] <= w[i]; i++)
        {
    
    
            ll k = (w[i] / prime[j] <= sqr) ? id1[w[i] / prime[j]] : id2[n / (w[i] / prime[j])];
            g[i] = g[i] - (g[k] - sum[j - 1]);
        }
    }
    return g[id2[1]];
}

int main()
{
    
    
    init();
    ll n;
    scanf("%lld", &n);
    printf("%lld\n", solve(n));
    return 0;

}

Supongo que te gusta

Origin blog.csdn.net/weixin_43891021/article/details/108890066
Recomendado
Clasificación