Strange Sum

题目大意:

对于一个大于$1$的正整数$x$,定义$v(x)$为不超过$x$的最大质数,$u(x)$为大于$x$的最小质数。

给定$n(n\le10^9)$,求:
$$\sum_{i=2}^n\frac{1}{v(i)\cdot u(i)}$$

多组数据,要求按最简分数形式输出。

 

分析:

对于任意两个相邻质数$p_1$、$p_2$,取任意整数$x\in[p_1,p_2)$,都满足:$\frac{1}{v(i)\cdot u(i)} = \frac{1}{p_1\cdot p_2}$,即这些数的和为$\frac{p_2-p_1}{p_1\cdot p_2} = \frac{1}{p_1} - \frac{1}{p_2}$。

那么,当$n+1$为质数时,设$P_i$为不大于$n+1$的质数,则
$$\sum_{i=2}^n\frac{1}{v(i)\cdot u(i)}=\sum_{i=1}^{k}(\frac{1}{p_i}-\frac{1}{p_i+1})=\frac{1}{2}-\frac{1}{n+1}$$

而当$n$不为质数时,找到小于$n$的最大质数$P$,计算出$[2,P-1]$区间内的答案,$[P,n]$区间内的答案暴力求就好了。

 

代码:

 1 #include <cstdio>
 2 
 3 int t, n, f[100010], p[100000], pn;
 4 int p1, p2;
 5 long long fm, fz;
 6 
 7 inline bool isPrime(int x)
 8 {
 9     if (x <= 100000)
10     {
11         return f[x] == 0;
12     }
13     for (int i = 0, j; i < pn; i++)
14     {
15         j = p[i];
16         if (j * j > x)
17         {
18             break;
19         }
20         if (x % j == 0)
21         {
22             return 0;
23         }
24     }
25     return 1;
26 }
27 
28 long long gcd(long long a, long long b)
29 {
30     return b == 0 ? a : gcd(b, a % b);
31 }
32 
33 int main()
34 {
35     f[0] = f[1] = 1;
36     pn = 0;
37     for (int i = 2; i <= 100000; i++)
38     {
39         if (f[i] == 0)
40         {
41             p[pn++] = i;
42             for (int j = i + i; j <= 100000; j += i)
43             {
44                 f[j] = i;
45             }
46         }
47     }
48     scanf("%d", &t);
49     while (t--)
50     {
51         scanf("%d", &n);
52         for (p1 = n; p1 > 1; p1--)
53         {
54             if (isPrime (p1) == 1)
55             {
56                 break;
57             }
58         }
59         for (p2 = n + 1; p2 < 1000000010; p2++)
60         {
61             if (isPrime (p2) == 1)
62             {
63                 break;
64             }
65         }
66         fm = (long long) p1 * p2 * 2;
67         fz = (long long) p2 * (p1 - 2) + (long long) (n - p1 + 1) * 2;
68         long long k = gcd(fz, fm);
69         fz /= k;
70         fm /= k;
71         printf("%lld/%lld\n", fz, fm);
72     }
73 }

 

posted @ 2015-06-25 20:43  Lightning34  阅读(162)  评论(0编辑  收藏  举报