打卡信奥刷题(1635)用C++信奥 P7588 双重素数(2021 CoE-II A)

P7588 双重素数(2021 CoE-II A)

题目描述

素数(质数)是指在大于 111 的自然数中,除了 111 和它本身以外不再有其他因数的自然数。定义双重素数为这样的素数:它的各位数字之和也是一个素数。给定一个闭区间,试确定在该区间内双重素数的个数。

输入格式

输入包含多组测试数据。

输入第一行包含一个整数 TTT,表示测试数据的组数。接下来每行一组测试数据,每组测试数据包含以空格分隔的两个整数 LLLRRR

输出格式

每组测试数据输出一行,包含一个整数,表示在闭区间 [L, R][L,\ R][L, R] 内双重素数的个数。

输入输出样例 #1

输入 #1

4
3 3
4 4
1 5
1 15

输出 #1

1
0
3
5

说明/提示

样例说明

111151515 共有 666 个素数:222333555777111111131313。前五个素数各自的数字之和也是素数,因此都是双重素数。素数 131313 的各位数字之和为 444,不是素数,故 131313 不是双重素数。


数据范围

  • Subtask 1111≤L≤R≤1021 \le L \le R \le 10^21LR102101010 分。
  • Subtask 2221≤L≤R≤1041 \le L \le R \le 10^41LR104202020 分。
  • Subtask 3331≤L≤R≤1061 \le L \le R \le 10^61LR106606060 分。
  • Subtask 4441≤L≤R≤1081 \le L \le R \le 10^81LR108101010 分。

对于 100%100\%100% 的数据,1≤T≤1001 \le T \le 1001T100


提示(数据已经加强)

最后一个子任务要求你的程序必须具有较高的空间使用效率和时间效率,否则容易超出内存限制或时间限制。

C++实现

#include <bits/stdc++.h>
using namespace std;
#define GET(x) (B[x >> 5] & (1 << (x & 0x1F)))
#define SET(x) (B[x >> 5] |= (1 << (x & 0x1F)))
const int MAXB = 100000001, MAXN = 6000000;
int B[MAXB >> 5], dp[MAXN], pc = 0, dpc = 0;
int magic[25] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
inline bool isDoublePrime(int n){
    int ds = 0;
    while (n) ds += (n % 10), n /= 10;
    for (int i = 0; i < 25; i++)
        if (ds == magic[i])
            return true;
    return false;
}
int main(int argc, char *argv[]){
    for (int i = 2; i < MAXB; i++)    {
        if (!GET(i)) dp[++pc] = i;
        for (int j = 1; j <= pc && i * dp[j] < MAXB; j++)        {
            SET(i * dp[j]);
            if (i % dp[j] == 0) break;
        }
    }
    for (int i = 1; i <= pc; i++) if (isDoublePrime(dp[i])) dp[++dpc] = dp[i];
    int cases;
    cin >> cases;
    for (int cs = 1; cs <= cases; cs++)    {
        int L, R;
        cin >> L >> R;
        L = upper_bound(dp + 1, dp + dpc + 1, L - 1) - dp - 1;
        R = upper_bound(dp + 1, dp + dpc + 1, R) - dp - 1;
        cout << R - L << '\n';
    }
    return 0;
}

在这里插入图片描述

后续:

接下来我会不断用C++来实现信奥比赛中的算法题、C++考级编程题实现、白名单赛事考题实现,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值