首页 > 其他 > 详细

Timus: [2070. Interesting Numbers]

时间:2019-02-23 20:33:11      阅读:193      评论:0      收藏:0      [点我收藏+]

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;
}
View Code

 

Timus: [2070. Interesting Numbers]

原文:https://www.cnblogs.com/knull/p/10424028.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!