题目
In many programming competitions, we are asked to find (or count the number of) Prime Factors of an integer i. This is boring. This time, let’s count the number of Non-Prime Factors of an integer i, denoted as NPF(i).
For example, integer 100 has the following nine factors: {1,2–,4,5–,10,20,25,50,100}. The two which are underlined are prime factors of 100 and the rest are non-prime factors. Therefore, NPF(100) = 7.
Input
The first line contains an integer Q (1≤Q≤3⋅106) denoting the number of queries. Each of the next Q lines contains one integer i (2≤i≤2⋅106).
Output
For each query i, print the value of NPF(i).
Warning
The I/O files are large. Please use fast I/O methods.
Sample Input 1
4
100
13
12
2018
Sample Output 1
7
1
4
2
题意要你求一个数的非素数因子个数,一开始是想打素数表,然后每输入一个数都计算它的因子总数并且减去这些因子在素数表中出现的个数,但不可避免地超时,后面了解到队友的思路,觉得蛮不错的,他用一个数组直接记录i这个数的非素数因子个数,这样输入的数直接就是数组下标,输出对应值即可,比原来快了不少。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define MAX 2000000
using namespace std;
int a[MAX+5],b[MAX+5]; //a[i]表示i这个数是否为素数,b[i]表示i的非素数因子个数
void sushu() //普通素数筛法 Nloglog(N)
{
a[1]=1;
int m=sqrt(MAX+0.5);
for(int i=2;i<=m;i++){
if(!a[i]){
for(int j=i*i; j<=MAX;j+=i){
a[j]=1;
}
}
}
}
void fun()
{
for(int i=1;i<=sqrt(MAX+0.5);i++)
{
int x = MAX/i;
for(int j=i;j<=x;j++){
if(a[i]){
b[i*j]++;
}
if(a[j]&&i!=j){
b[i*j]++;
}
}
}
}
int main()
{
sushu();
fun();
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
printf("%d\n",b[n]);
}
return 0;
}
下面贴出另一种实现方式的代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 2000000
using namespace std;
int vis[2000005],a[2000005];
int main()
{
memset(vis,0,sizeof(vis));
for(int i=2;i<=sqrt(N+0.5);i++){
if(!vis[i]){
for(int j=2*i;j<=N;j+=i) vis[j]=1;
}
}
for(int i=2;i<=N;i++){
if(vis[i]==1){
for(int j=i;j<N;j+=i){
a[j]++;
}
}
}
int t;
cin>>t;
while(t--)
{
int n;
scanf("%d",&n);
printf("%d\n",a[n]+1);
}
return 0;
}