Interesting Numbers URAL - 2070 【解题思路】

本文解析了一个趣味数学问题,Nikolay与Asya对整数的兴趣不同:前者偏爱质数,后者关注约数为质数的数。解决两人共同兴趣的数在给定区间[L,R]内的个数,涉及质因数分解和欧拉筛的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Interesting Numbers

题目+样例

Nikolay and Asya investigate integers together in their spare time. Nikolay thinks an integer is interesting if it is a prime number. However, Asya thinks an integer is interesting if the amount of its positive divisors is a prime number (e.g.,number 1 has one divisor and number 10 has four divisors).
Nikolay and Asya are happy when their tastes about some integer are common. On the other hand, they are really upset when their tastes differ. They call an integer satisfying if they both consider or do not consider this integer to be interesting. Nikolay and Asya are going to investigate numbers from segment [L; R] this weekend. So they ask you to calculate the number of satisfying integers from this segment.

Input
In the only line there are two integers L and R (2 ≤ L ≤ R ≤ 10^12).

Output
In the only line output one integer — the number of satisfying integers from segment [L; R].

3 7

output: 4

2 2

output: 1

77 1010

output: 924

解题思路

首先题目告诉你 有两个人,大N喜欢质数不喜欢合数;大A喜欢约数【能整除】的数量为质数的,不喜欢数量不是质数的
现在给你一个区间l-r问里面有多少个他们态度一致的数【要么都喜欢,要么都不喜欢】
首先我们我们要将数拆成几个部分来分段求解
1.质数
质数的分解只有本身和1,数量2是质数,所以大家都喜欢

2.合数
合数中又要分类,首先大N是不喜欢的,那么就会出现大A匹配情况: 不喜欢-不喜欢,不喜欢-喜欢的情况;

一个合数能有多少个能整除的?这个就需要用到质因数的推论了:合数质因数分解后质因数幂+1之积【排列组合问题】

所以约数要是个数要为质数,只会出现在合数是某一个质数的n方的情况下,其他情况下质因数个数>2,约数个数是幂+1之积,一定是合数【能拆,当时我没从质数n方这个地方绕出来】

可以得到不是质数的n方的大A不喜欢

是质数的n方时,约数个数就是n+1。n+1是质数,大A喜欢;n+1不是质数,大A不喜欢。

所以我们只需要排除范围内是质数n方,n+1是质数的数字;其他情况两人态度一致

【用到的算法,欧拉筛==线性筛】
1012只需要就求出106的内的素数就行了,至于为什么因为106的平方就是1012,所以1012内质因数分解不会超过106

求出素数后就看每个素数的n方n+1是不是质数就行了,算出0-l-1区间剩下的,0-r区间剩下的,两个剩下的相减完事!orz

代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define ll long long
const ll N= 1e6+100;
ll num[N],prime[N],pos=0;
void init()
{
	for(ll i=2;i<=N-100;i++)
	{
		if(!num[i])
		{
			prime[pos++]=i;
			num[i]=i;
		}
		for (ll j=0;j<pos;j++)
		{
			if (prime[j]>num[i]||prime[j]>1.0*(N-100)/i)break;
			num[prime[j]*i]=prime[j];
		}
	}
}
ll solve (ll x)
{
	ll ans=0;
	for (ll i=0;i<pos;i++)
	{
		ll cnt= prime[i];
		cnt*=prime[i];
		if (cnt>x)break;
		for (ll j=2;;j++)
		{
			if (cnt>x)break;
			if (num[j+1]==j+1) ans++;
			cnt*=prime[i];
		}
	}
	return x-ans;
}
int main ()
{
	init();
	ll l,r;
	cin>>l>>r;
	cout<<solve(r)-solve(l-1)<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个人心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值