题目链接:UOJ
这道题,也算是min_25的一个基础应用吧。。。
我们要求$$\sum_{i=1}^nf(i)$$,其中$f(i)$表示$i$的次大质因子。
按照套路,我们设$$S(n,j)=\sum_{i=1}^n[minp(i)>P_j]f(i)$$
所以$$S(n,j)=\sum_{k>j,P_k\leq \sqrt{n}}\sum_{e>0,P_k^{e+1}\leq n}(S(\lfloor\frac{n}{P_k^e}\rfloor,k)+P_k\sum_{i=P_k}^{\lfloor\frac{n}{P_k}\rfloor}[i\in Prime]$$
素数个数用min_25筛可以很快求出来。
1 #include<bits/stdc++.h> 2 #define Rint register LL 3 using namespace std; 4 typedef long long LL; 5 const int N = 1000003; 6 LL Sqr, pri[N], tot, g[N], w[N], id1[N], id2[N], cnt; 7 bool notp[N]; 8 inline void init(int m){ 9 notp[0] = notp[1] = true; 10 for(Rint i = 2;i <= m;i ++){ 11 if(!notp[i]) pri[++ tot] = i; 12 for(Rint j = 1;j <= tot && i * pri[j] <= m;j ++){ 13 notp[i * pri[j]] = true; 14 if(!(i % pri[j])) break; 15 } 16 } 17 } 18 inline LL solve(LL n, LL x, int y){ 19 if(x <= 1) return 0; 20 // printf("n = %lld, x = %lld, y = %d\n", n, x, y); 21 LL ans = 0; 22 for(Rint k = y + 1;k <= tot && pri[k] * pri[k] <= x;k ++){ 23 for(Rint pe = pri[k];pe * pri[k] <= x;pe *= pri[k]){ 24 LL kk = (x / pe <= Sqr) ? id1[x / pe] : id2[n / (x / pe)]; 25 ans += solve(n, x / pe, k) + pri[k] * (g[kk] - k + 1); 26 } 27 } 28 return ans; 29 } 30 inline LL solve(LL n){ 31 Sqr = sqrt(n); 32 tot = cnt = 0; 33 init(Sqr); 34 // for(Rint i = 1;i <= tot;i ++) printf("pri[%d] = %d\n", i, pri[i]); 35 for(Rint i = 1, last;i <= n;i = last + 1){ 36 w[++ cnt] = n / i; 37 last = n / w[cnt]; 38 g[cnt] = w[cnt] - 1; 39 if(w[cnt] <= Sqr) id1[w[cnt]] = cnt; 40 else id2[last] = cnt; 41 } 42 // for(Rint i = 1;i <= cnt;i ++) printf("w[%d] = %d\n", i, w[i]); 43 for(Rint i = 1;i <= tot;i ++) 44 for(Rint j = 1;j <= cnt && pri[i] * pri[i] <= w[j];j ++){ 45 LL k = (w[j] / pri[i] <= Sqr) ? id1[w[j] / pri[i]] : id2[n / (w[j] / pri[i])]; 46 g[j] -= g[k] - i + 1; 47 } 48 return solve(n, n, 0); 49 } 50 int main(){ 51 LL l, r; 52 scanf("%lld%lld", &l, &r); 53 printf("%lld\n", solve(r) - solve(l - 1)); 54 }
原文:https://www.cnblogs.com/AThousandMoons/p/10833634.html