Interesting Numbers URAL - 2070 数论

本文探讨了如何解决一个特定的算法问题:在给定区间内找到既满足素数条件又满足因子个数为素数的整数。通过逆向思维,文章提供了一种高效的解决方案,特别是针对如何确定一个数的因子数量为素数这一挑战。

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

题目链接http://acm.timus.ru/problem.aspx?space=1&num=2070


题意:给定区间L R,求条件二者都满足,或者都不满足的数字有多少个。

条件1:素数 ,条件2:因子的个数是素数。


思路:  正向来找非常难找,反向来看。只要是素数,两者条件都满足。合数的话,不满足条件1,再找出满足条件2的,用总数R-L+1减去这个数即可。

关键是因子的个数是素数,这个怎么来找呢。

假设一个数字可以被分解成 X = p1^a+p2^b 形式,p1,p2都是素因子,ab为指数

那么这个数的因子是 p1,p1*p1,...,p1^a  (p1组合)     ,p2,p2*p2,...,p2^b(p2组合), p1^p2,p1*p2^2,...p1^a*p2^b(p1和p2组合),总数是  a+b+a*b+1个因子,即(a+1)*(b+1) ,三个素因子的时候 (a+1)*(b+1)*(c+1) 

所以,只有当不同的素因子的个数为1的时候,并且指数+1为素数的时候,才是满足的。再用总数减掉即可。

#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<cmath>
#include<iostream>  
#include<vector>  
using namespace std; 
typedef long long LL; 
const int maxn = 1e6+10; 
vector<int> v;
int vis[maxn];   
void init() 
{
	vis[1] = 1; 
	for ( int i=2; i<maxn; i++ ) {
		if ( vis[i]==0 ) {
			v.push_back(i); 
			for ( int j=i+i; j<maxn; j+=i ) vis[j] = 1; 
		}
	} 
}
int main(){  
	init(); 
	LL l,r; 
	cin>>l>>r; 
	LL ans = r-l+1; 
	for ( int i=0; i<v.size(); i++ ) {
		LL cur = 1 ; 
		int sum = 0 ; 
		if ( v[i]*v[i]>r ) break; 
		while ( cur<l ) { cur *= v[i]; ++sum; }
		while ( cur<=r  ) {
			if ( sum>1 && vis[sum+1]==0 ) --ans; 
			cur *= v[i]; ++sum; 
		}
 	}
 	cout<<ans<<endl; 
    return 0;  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值