【LOJ6202】叶氏筛法(阉割Min_25筛)

Description

计算给定区间内所有质数之和。


Solution

f ( i ) = i ,即计算Min_25筛中的 h ( i )
h i , j = 1 p j p 1 p i f ( p ) ,即埃氏筛 i 次后没有被标记成非素数的数的函数值的和。
转移:当 j p i 2 时, h i , j = h i 1 , j f ( p i ) ( h i 1 , j p i h i 1 , p i 1 )
否则 h i , j = h i 1 j

答案为 h ( x ) = h | P | , x


Code

/**************************************
 * Au: Hany01
 * Prob: LOJ6202
 * Date: Jun 17th, 2018
 * Email: [email protected]
**************************************/

#include<bits/stdc++.h>

using namespace std;

typedef unsigned long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
///////////////////////
#define __int128 double
///////////////////////
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = j; i < i##_end_; ++ i)
#define For(i, j ,k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define SZ(a) ((int)(a.size()))
#define ALL(a) a.begin(), a.end()
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define y1 wozenmezhemecaia 
#ifdef hany01
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif

template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }

inline LL read() {
    register char c_; register LL _, __;
    for (_ = 0, __ = 1, c_ = getchar(); !isdigit(c_); c_ = getchar()) if (c_ == '-')  __ = -1;
    for ( ; isdigit(c_); c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
    return _ * __;
}

const int maxn = 340005, maxs = 340000, N = 340000;

int tot, pri[maxn >> 2];
LL sum[maxn];

inline void Sieve()
{
    static bitset<maxn> nap;
    static int t;
    nap.reset();
    For(i, 2, N) {
        sum[i] = sum[i - 1];
        if (!nap.test(i)) pri[++ tot] = i, sum[i] += i;
        for (register int j = 1; j <= tot && (t = pri[j] * i) <= N; ++ j) {
            nap.set(t);
            if (!(i % pri[j])) break;
        }
    }
}

inline __int128 Sum(LL x) { return (__int128)x * (x + 1) / 2; }

void print(__int128 x)
{
    printf("%.f\n", x);
    /*if (!x) return (void)putchar(48);
    static int sta[111],tp;
    for(tp=0; x; x /= 10) sta[++ tp] = x % 10;
    for(; tp; putchar(sta[tp --] ^ 48)) ;*/
}


__int128 Calc(LL x)
{
    static int cnt, t1[maxn], t2[maxn], id;
    static LL  l, r, t, lst[maxs << 1];
    static __int128 h[maxs << 1];
    cnt = 0;
    for (l = 1; l <= x; l = r + 1)
        r = x / (t = (x / l)), lst[++ cnt] = t, h[cnt] = Sum(t) - 1,
        t >= N ? t2[x / t] = cnt : t1[t] = cnt;

    For(j, 1, tot) {
        register LL bot = (LL)pri[j] * pri[j];
        if (bot > x) break;
        for (register int i = 1; i <= cnt && lst[i] >= bot; ++ i)
            t = lst[i] / pri[j], id = t >= N ? t2[x / t] : t1[t],
            h[i] -= (__int128)pri[j] * (h[id] - sum[pri[j] - 1]);
    }
    return h[x >= N ? t2[1] : t1[x]];
}

int main()
{
#ifdef hany01
    File("loj6202");
#endif

    Sieve();
    static LL L = read(), R = read();
    print(Calc(R) - Calc(L - 1));

    return 0;
}
//西风多少恨,吹不散眉弯。
//    -- 纳兰性德《临江仙·寒柳》

猜你喜欢

转载自blog.csdn.net/hhaannyyii/article/details/80765572
今日推荐