UOJ188 【UR #13】Sanrd

题目链接: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 }
UOJ188

 

posted @ 2019-05-08 18:27  mizu164  阅读(366)  评论(0编辑  收藏  举报