题目大意:
对于一个大于$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 }
时间: 2024-10-15 17:42:03