您的位置:首页 > 其它

Interesting Numbers URAL - 2070 数论

2017-04-05 09:05 357 查看
题目链接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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: