这里
题意:说白了就是求这个
其中表示次小质因子,规定1和质数的次小质因子为0
做法:这道题是一道min25筛法的题,但不过不是普通的积性函数求和,需要对该算法有一定的理解。
首先我们还是以表示在范围内最小质因子不小于的和。
对于质数部分没有贡献为0,对于合数部分我们枚举最小质因子的幂次,那么合数分为两部分,一部分,这两部分中前一部分的答案为,后一部分的答案这个合数的答案,因此
后面关于质数的计数部分,直接函数的处理即可。
听它们说还可以有另外一种写法就是强制第y层的质数为最大质因子,这样递推,我也没有这样写过,但不过估计比这个复杂。
#include "bits/stdc++.h"
using namespace std;
inline int read() {
int x = 0;
bool f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = 0;
for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
if (f) return x;
return 0 - x;
}
typedef long long ll;
const int maxn = 400010;
const ll mod = 1000000000 + 7;
ll quick(ll a, ll n, ll p) {
ll ans = 1;
for (; n; n >>= 1, a = a * a % p)
if (n & 1) ans = ans * a % p;
return ans;
}
int vis[maxn], sqr, cnt = 0;
ll suf1[maxn], suf2[maxn], inv2, inv6, n, pri[maxn];
void init(int lim) {
vis[1] = 1;
for (int i = 2; i <= lim; i++) {
if (!vis[i]) {
pri[++cnt] = i;
}
for (int j = 1; j <= cnt && i * pri[j] <= lim; j++) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) break;
}
}
}
int id1[maxn], id2[maxn], m = 0;
ll w[maxn << 1], g[maxn << 1], h[maxn << 1];
int getid(ll x) {
if (x <= sqr) return id1[x];
return id2[n / x];
}
void calc1() {
for (ll l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
w[++m] = n / l;
g[m] = w[m] - 1;
if (w[m] <= sqr) id1[w[m]] = m;
else id2[r] = m;
}
for (int j = 1; j <= cnt; j++) {
for (int i = 1; i <= m && pri[j] * pri[j] <= w[i]; i++) {
int k = getid(w[i] / pri[j]);
g[i] -= g[k] - j + 1;
}
}
}
ll sum(ll x, int y) {
if (x <= 1 || pri[y] > x) return 0;
int k = getid(x);
ll ret = 0;
for (int i = y; i <= cnt && 1ll * pri[i] * pri[i] <= x; i++) {
ll t1 = pri[i], t2 = 1ll * pri[i] * pri[i];
for (int e = 1; t2 <= x; ++e, t1 = t2, t2 *= pri[i]) {
ret += (sum(x / t1, i + 1) + 1ll * pri[i] * (g[getid(x / t1)] - i + 1));
}
}
return ret;
}
int main() {
// inv2 = quick(2, mod - 2, mod);
// inv6 = quick(6, mod - 2, mod);
ll l, r;
cin >> l >> r;
n = r;
sqr = sqrt(n);
init(sqr);
calc1();
ll ans = sum(n, 1);
n = l - 1;
sqr = sqrt(n);
m = 0;
calc1();
ans = ans - sum(n, 1);
cout << ans << endl;
return 0;
}
来源:CSDN
作者:KXL5180
链接:https://blog.csdn.net/KXL5180/article/details/104375666