ABC 250 | D - 250-like Number
题目描述
给定一个数,找出范围内,可以表示成的形式的数的个数,其中且、均为质数。
数据范围
题目解析
首先观察数据范围发现不可以枚举,然后判断该数是否满足题目描述性质。考虑逆向思维,枚举并构造满足题目要求的数,然后判断是否在范围内。
所以只需预处理出范围内的质数,可以用线性筛法。
预处理得到范围内的质数后(不到个),可以通过两种方法计算在范围内的的个数。(需注意,由于和均为质数,所以只要和不完全相同,组合出的数就不同,可以从质因数分解的角度证明)。
方法一:二分查找
枚举所有的,查找满足条件的。
假设为,起初为满足设置边界条件为,这样做无法通过样例。后调整为,然后判断是否有,可以AC。
方法二:双指针算法
容易发现与移动的单调性,因此可用双指针算法,每次答案加上两个指针之间的距离。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
int primes[N], cnt;
bool st[N];
ll n;
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
ll check(ll p, ll q){
double x = (double)p * (double)q * (double)q * (double)q;
if(x > 4e18) return 4e18;
return p * q * q * q;
}
int main()
{
get_primes(1e6);
scanf("%lld", &n);
ll ans = 0;
for(int i = 0; i < cnt; i ++){
ll p = primes[i];
int l = 0, r = cnt;
while(l < r){
int mid = l + r + 1 >> 1;
ll q = primes[mid];
if(check(p, q) <= n) l = mid;
else r = mid - 1;
}
if(l > i) ans += (l - i);
}
printf("%lld\n", ans);
return 0;
}
模板积累
//学会处理一个爆ll的数
ll check(ll p, ll q){
double x = (double)p * (double)q * (double)q * (double)q;
if(x > 4e18) return 4e18;
return p * q * q * q;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架