Description
计算给定区间内所有质数之和。
Solution
设
f(i)=i
f
(
i
)
=
i
,即计算Min_25筛中的
h(i)
h
(
i
)
。
设
h′i,j=∑1≤p≤jp为1,质数,或没有≤pi的质因子f(p)
h
i
,
j
′
=
∑
1
≤
p
≤
j
p
为
1
,
质
数
,
或
没
有
≤
p
i
的
质
因
子
f
(
p
)
,即埃氏筛
i
i
次后没有被标记成非素数的数的函数值的和。
转移:当时,
h′i,j=h′i−1,j−f(pi)(h′i−1,⌊jpi⌋−h′i−1,pi−1)
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−1j
h
i
,
j
′
=
h
i
−
1
′
j
答案为 h(x)=h′|P|,x h ( x ) = h | P | , x ′
Code
/**************************************
* Au: Hany01
* Prob: LOJ6202
* Date: Jun 17th, 2018
* Email: hany01@foxmail.com
**************************************/
#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;
}
//西风多少恨,吹不散眉弯。
// -- 纳兰性德《临江仙·寒柳》