codeforces 665F. Four Divisors(求n以内因子数是4的数的个数)

F. Four Divisors
time limit per test
10 seconds
memory limit per test
768 megabytes
input
standard input
output
standard output

If an integer a is divisible by another integer b, then b is called the divisor of a.

For example: 12 has positive 6 divisors. They are 12346 and 12.

Let’s define a function D(n) — number of integers between 1 and n (inclusive) which has exactly four positive divisors.

Between 1 and 10 only the integers 68 and 10 has exactly four positive divisors. So, D(10) = 3.

You are given an integer n. You have to calculate D(n).

Input

The only line contains integer n (1 ≤ n ≤ 1011) — the parameter from the problem statement.

Output

Print the only integer c — the number of integers between 1 and n with exactly four divisors.

Examples
input
10
output
3
input
20
output
5

题意:

输入一个数n,求n以内并且只有4个不同因子的数的个数

思路:

每一个数至少存在两个因子,1和本身。

一个数仅存在四个不同的因子,那么这个数必定是某个素数的3次方或者是两个不同素数的乘积

1、n以内且是某个素数的3次方得到个数,很好求,直接将n开三次方得到x,求x以内的素数的个数即可

2、两个不同素数的乘积,枚举较小的素数a,得到b=n/a,对于不同的a,求出b以内的素数的个数,相加去重即可

那么问题就转化成了数m以内的素数个数的问题,恰好可以套用模板:hdu 5901


#include 
using namespace std;
#define ll __int64

const int N=320005;   
ll phi[10005][105], p2[N], ans[N];  
int len, vis[N];  
  
void init(){  
    len = 0;  
    for(int i=2; i= m) return 1;  
    if(m<=10000 && n<=100) return phi[m][n];  
    return solve_phi(m, n-1) - solve_phi(m/p2[n-1], n-1);  
}  
  
ll solve_p2(ll m){  
    if(m < (ll)N) return ans[m];  
      
    ll y = (int)cbrt(m*1.0);  
    ll n = ans[y];  
    ll sum = solve_phi(m, n) + n -1;  
      
    for(ll i=n; p2[i]*p2[i]<=m; i++) 
        sum = sum - solve_p2(m/p2[i])+solve_p2(p2[i])-1;  
    return sum;  
}  

int main(){
	init();
	ll n;
	scanf("%I64d", &n);
	ll S = cbrt(n*1.0);
	S = solve_p2(S);
	ll tmp=0;
	for(int i=0; i=n) break;
		ll x = n/p2[i];
		ll s = solve_p2(x);
		s-=tmp+1;
		tmp = solve_p2(p2[i]);
		S+=s;
	}
	printf("%I64d\n", S);
	return 0;
} 





你可能感兴趣的:(CodeForces)