Timue: [2070. Interesting Numbers]
整个题目比较绕,
1. 质数: 全部符合要求(为什么呢?)
2. 合数:a. 有两种以上因子数的符合要求(想想基于质因子的指数计算因子数的公式);b.唯一质因子的指数加一不为质数就符合要求;c.除去前面的种类,则不符合要求。
所以,求出2.c即可得到答案。
整个思路知道好就比较好实现了:
1. 使用埃氏筛子(Sieve of Eratosthenes)求出所有质数;
2. 枚举所有质数的质数减一次幂;
3. 输出结果。
#include <stdio.h> #define MAX_N 1000000 int A[((MAX_N - 2) / 2 + 31) >> 5]; int test(int x) { return A[x >> 5] & (1 << (x & 31)); } void set(int x) { A[x >> 5] |= 1 << (x & 31); } int primes[78498] = {2}; int N = 1; void initialize() { for (int i = 0; 4 * i * i + 12 * i + 9 <= MAX_N; ++i) { if (!test(i)) { for (int z = 2 * i * i + 6 * i + 3; 2 * z + 3 <= MAX_N; z += 2 * i + 3) { set(z); } } } for (int i = 0; 2 * i + 3 <= MAX_N; ++i) { if (!test(i)) { primes[N++] = 2 * i + 3; } } } long long L, R; void input() { scanf("%lld%lld", &L, &R); } long long check(int p) { int k = 0; long long z = 1; long long ans = 0; for (int i = 1; i < N; ++i) { while (k + 1 < primes[i]) { z *= p; ++k; if(z > R) { return ans; } } ans += z >= L; } return ans; } long long solve() { long long ans = R + 1 - L; for (int i = 0; i < N && primes[i] * primes[i] <= R; ++i) { ans -= check(primes[i]); } return ans; } int main() { initialize(); input(); printf("%lld\n", solve()); return 0; }
Timus: [2070. Interesting Numbers]
原文:https://www.cnblogs.com/knull/p/10424028.html