Timus 2070 Interesting Numbers
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=2070
题目描述:
题目大意是给定范围[L, R],求该范围中interesting数的个数。
interesting数的定义为:
1.素数
2.不为素数且其正因子的个数不为素数个(如:6: 1,2,3,6)
计算正因子的个数一般使用的是分解质因数了,若 n = p1^a1 * p2^a2 * ... pm^am
那么正因子的个数为 k = (a1+1) * (a2+1) * ... * (am+1),因此:
若m>1,k必为非素数,则为interesting数,
若m=1,则a1+1为非素数即可
因此可以直接计算非interesting数的计算则为:m = 1, 且 a1+1为素数,但a1>1,因此可以用素数来筛选。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std ; 5 6 long long ll, rr ; 7 const int MAXM = 1000005 ; 8 bool is_prim[MAXM] ; 9 int prims[MAXM], totals ; 10 11 void init(){ 12 totals = 0 ; 13 memset(is_prim, true, sizeof(is_prim)) ; 14 for( int i = 2; i < MAXM; i++ ){ 15 if( is_prim[i] ){ 16 prims[totals++] = i ; 17 for( int j = 2; i*j < MAXM; j++ ) is_prim[i*j] = false ; 18 } 19 } 20 } 21 22 void solve(){ 23 init() ; 24 long long res = rr - ll + 1 ; 25 26 for( int i = 0; i < totals && prims[i]*prims[i] <= rr; i++ ){ 27 long long val = 1 ; 28 int num = 0 ; 29 for( int j = 1; j < totals; j++ ){ 30 for( int k = num; k < prims[j]-1; k++ ){ 31 val *= prims[i] ; 32 if( val > rr ) break ; 33 } 34 if( val > rr ) break ; 35 num = prims[j] - 1; 36 37 if( val >= ll && val <= rr ) res-- ; 38 } 39 } 40 41 cout << res << endl ; 42 } 43 44 int main(){ 45 freopen("1234.txt", "r", stdin) ; 46 cin >> ll >> rr ; 47 solve() ; 48 return 0 ; 49 }