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 }

 

posted @ 2016-04-08 20:59  ct_usl  阅读(288)  评论(0编辑  收藏  举报