2286

#include  < iostream >
#include 
< algorithm >
#include 
< cmath >
#include 
< assert.h >
using   namespace  std;

int  divisor[ 1000001 ]; // divisor[i]记录着i的一个非平凡质因数,如果i是质数则divisor[i]=0;
int  dp[ 1000001 ]; // dp[i]为i的非1因子的和
int  f[ 1000001 ]; // f[i]为i的真因子的和

void  init()
{
    
//
     for ( int  i = 2 ;i <= 1000 ;i ++ ){
        
if ( ! divisor[i]){
            
for ( int  j = i * i;j <= 1000000 ;j += i){
                divisor[j]
= i;
            }
        }
    }
    
// DP
     for ( int  i = 2 ;i <= 1000000 ;i ++ ){
        
if ( ! divisor[i]){
            dp[i]
= i;
        }
        
else  {
            
int  x = divisor[i];
            
while (i % x == 0 ){
                x
*= divisor[i];
            }
            x
/= divisor[i];
            dp[i]
= dp[i / divisor[i]] + x * dp[i / x] + x;
        }
    }
    
// calulate f[]
    f[ 1 ] = 0 ;
    
for ( int  i = 2 ;i <= 1000000 ;i ++ ){
        f[i]
= dp[i] - i + 1 ;
    }
}

// 在[b,e),之间返回一个指针p,使得*(p-1) <=x && x<*p,特别地,当x<*b时返回b ,当*(e-1)<=x时返回e 
int *  binary( int *  b, int *  e, int  x)
{
       
int   * mid;
       
if (x <* b) return  b;
       
if ( * (e - 1 ) <= x) return  e;
       
while (b < e - 2 ){
           mid
= b + (e - b) / 2 ;
           
if ( * mid <= x)
               b
= mid;
           
else
               e
= mid + 1 ;
       }
       
return  e - 1 ;
}

int  main()
{
    init();
    sort(f
+ 1 ,f + 1000000 + 1 );
    
int  m,cnt;
    
while (scanf( " %d " , & m) != EOF){
        cnt
= binary(f + 1 ,f + 1000000 + 1 ,m) - (f + 1 );
        printf(
" %d " ,cnt);
    }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值