Interesting Numbers URAL - 2070 数论

    xiaoxiao2021-03-25  61

    题目链接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; }

    转载请注明原文地址: https://ju.6miu.com/read-41030.html

    最新回复(0)