ural 2070 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].
Example
input output
3 7
4
2 2
1
77 1010
924

题意:
在[L, R]之间
求:
1、x是个素数
2、因子个数是素数
同时满足两个条件,或者同时不满足两个条件的数的个数!

素数肯定是满足条件的 由于数量太大,如果直接求有多少个满足这两个条件的 没有共通条件,全扫还得分类讨论,所以我们求反面。x是个素数 满足。x是个合数同时因子个数是个合数满足。x是个素数同事因子个数是个质数,不满足。只有一类不满足,求出来数量即可。求因子数量用到了因式分解。
由于素数相乘必然为合数。每一个合数都可以有几个质数相乘得到。而且分析可知,如果是两个不同的质数,那么得到因子数为(n+1)(m+1),这几天接触到的数论基础。一个数的因子数是他每一个质因子的个数(n+1)(m+1)的排列组合 的方案总数,因为每一个质因素都有(单个质因子数量+1)个取法 就好比 12 = 2^2 * 3 ,12的因子可以表示成 (2^0, 2^1, 2^2中选一个),(3^0, 3^1选一个)
所以12有3*2个约数 其中因子6可以由 2^1*3^1
http://blog.sina.com.cn/s/blog_818d3d9301017436.html

所以一个多个质因素组合组成的合数它的因子数(n+1)*(m+1)必定不止1和它本身,所以肯定不是素数。 1 ,(n+1),(m+1)就已经是3个了。
所以只要遍历每一个单素数组成的合数 而且是在l和r范围内的因子数+1是否是素数即可,是即可删掉。
如果只有一个质因子就是 n+1,有多个就是(n+1)(m+1)….一直乘下去

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxx=1e6;
int v[maxx];
vector<int> prime;
void perpare()
{
    for(int i=2;i<=maxx;i++)
    {
        if(!v[i])
        {
            prime.push_back(i);
            for(int j=i*2;j<=maxx;j+=i)
            {
                v[j]=1;
            }
        }
    }
}

LL solve(LL l,LL r)
{
    LL coun=r-l+1;
    for(int i=0;i<prime.size();i++)
    {
        LL ans=0;
        LL num=1;
        while(num<l)  num*=prime[i],ans++;
        while(num<=r) 
        {
            if(ans>1&&!v[ans+1]) coun--;
            num*=prime[i],ans++;
        }
    }
    return coun;
}
int main()
{
    long long  L,R;
    cin>>L>>R;
    perpare();
    cout<<solve(L,R)<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值