UOJ188. 【UR13】Sanrd 发表于 2020-05-21 | 阅读数 看到因子,还是多想想Min_25筛吧。 解释下 如果$p_k$是次大因子,那么只要选出$[p_k,n/p_j^e]$中的质数. 如果$p_k$不是是次大因子,那么次大因子就是$\sum_{i=1}^{n/p_k^e}[min(i)>p_k] f(i)$. 注意边界$p_j> n^2$,还是恒没有贡献。 代码 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394#include <bits/stdc++.h>using namespace std;typedef long long ll;#define pii pair<int, int>#define mk make_pairconst int N = 1e6 + 10;const int mod = 1e9 + 7;struct Min_25{ ll n, Lim; ll g[N], p[N]; int pos1[N], pos2[N], cnt; int pcnt; ll pr[N], npr[N]; void Prime_init(int X) { for (int i = 2; i <= X; i++) { if (!npr[i]) { pr[++pcnt] = i; } for (int j = 1; j <= pcnt && pr[j] * i <= X; j++) { npr[i * pr[j]] = 1; if (i % pr[j] == 0) break; } } } int Getcnt(ll x) { return (x <= Lim) ? pos1[x] : pos2[n / x]; } ll S(ll x, int y) { if (pr[y] >= x || x <= 2) return 0; ll ans = 0; for (int i = y + 1; i <= pcnt && pr[i] * pr[i] <= x; i++) { ll pe = pr[i]; for (int e = 1; pe * pr[i] <= x; e++, pe = pe * pr[i]) { int k = Getcnt(x / pe); ans += (S(x / pe, i)); //cout << pr[i] << " " << e << ' ' << g[k] - (i - 1) << endl; ans += pr[i] * (g[k] - (i - 1)); } } return ans; } ll get(ll x) { n = x; Lim = sqrt(n); Prime_init(Lim); for (ll i = 1, j; i <= n; i = j + 1) { j = n / (n / i); ll k = n / i; p[++cnt] = k; g[cnt] = k - 1; if (k <= Lim) pos1[k] = cnt; else pos2[n / k] = cnt; } for (int i = 1; i <= pcnt; i++) { for (int j = 1; j <= cnt && 1ll * pr[i] * pr[i] <= p[j]; j++) { int k = Getcnt(p[j] / pr[i]); g[j] -= g[k] - (i - 1); } } return S(n, 0); }} T1, T2;ll l, r;int main(){ // cin >> r; // cout << T1.get(r) << endl; cin >> l >> r; cout << T2.get(r) - T1.get(l - 1) << endl;}