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⋅10^6) denoting the number of queries. Each of the next Q lines contains one integer i (2≤i≤2⋅10^6).

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 Sample Output 1
4
100
13
12
2018
7
1
4
2

题目大意:第一行给一个Q,代表Q次查询,接下来Q行,每行一个整数i,求NPF(i)

    拿样例100来说,100的因子有(1,2,4,5,10,20,25,50,100)共9个,其中2和5是质数(一个大于1的自然数,除了1和它本身外,不能被其他自然数整除),应去掉,剩下7个。

    所以NPF(100)= 7

    拿样例13来说,13的因子有(1,13)共2个,其中13是质数,去掉后,剩下1个。

    所以NPF(13)= 1

解题思路:1.先预处理出1-2*10^6的质数。可以用eratosthenes筛法,时间复杂度O(NloglogN)(某位网友说的)

     2.预处理答案,先看代码:

for(int i = ; i <= ; ++i){
int rt = /i;
for(int j = i; j <= rt; ++j){
if(vis[i]){//非质数
++ans[i*j];
}
if(vis[j] && i!=j){
++ans[i*j];
}
}
}

  第一个for循环,表示1到2*10^6的数。

  第二个for循环,对于当前的数i,对 i 到 i*rt 进行处理

  举个栗子,对于100来说,ans【100】初始化是0

  第一个循环到1时

    在第二个循环中:判断1是非质数第一个if中必然会有1*100=100,即ans【100】++;(100<rt,必然出现)

            第二个if中会出现j=100,100是非质数,又100*1=100,即ans【100】++;

  tip:当i=100时,j 从100开始累加而且 j 不会回溯,所以100=1*100这一种分解方法会在i=1的时候处理出来

    即ans【100】+=2;

  第一个循环到2时

    在第二个循环中:第一个if  判断2是质数,跳过(相当于把2这个因子剔除了,即没有加入答案中)

            第二个if  j=50时,50是非质数,又50*2=100,所以ans【100】++;

  第一个循环到4时

    在第二个循环中:第一个if  判断4是非质数,4*25=100,ans【100】++;

            第二个if  j=25时,25是非质数,25*4=100,所以ans【100】++;

  第一个循环到5时

    在第二个循环中:第一个if  判断5是质数,跳过,

            第二个if  j=20时,20是非质数,20*5=100,所以ans【100】++;

  第一个循环到10时

    在第二个循环中:第一个if  判断10是非质数,10*10=100,ans【100】++;

            第二个if  j=10时,10是非质数,但是i=j,跳过(相同因子处理一次即可,在第一个if处理了)

  第一个循环到20时:20*5=100,但是5不会出现,因为j是从20开始不断累加,ans【100】已经处理结束了,从上面分析可以看出ans【100】=7;

  类似的,每个答案都可以在这2个循环中处理出来。

  时间上:当i=1来说,rt=2*10^6,j会从1加到2*10^6

      当i=2,rt=10^6,   j会从2加到10^6;

      ......  

      当i=10,rt=2*10^5,j会从10加到2*10^5(此时数量级已经降了一级)

      ...

      当i=100,rt=2*10^4,j会从1加到2*10^4

      ....

      当i=1000,rt=2*10^3,j会从1000加到2000(共1000次)

      .....

      当i=sqrt(2*10^6) rt=i,第二层循环直接跳过,后面一样,都是1次

把它们加起来,大概也就10^7左右(目测估计法算的)

预处理10^6左右,Q个问题3*10^6,加起来数量级也在10^7

某位大佬说10^7的数量级一般都能在1s跑完,要看测评机

一开始我是对每次枚举每个数的因数(1-sqrt(n)),然后想办法优化,结果都是超时....((╯‵□′)╯︵┻━┻)

启示:优化的时候想想办法让回溯的次数少一点。

AC代码:

#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
bool vis[];
int ans[];
void init()
{
//开始筛,vis=1表示该数不是质数
vis[]=;
int m=sqrt(+0.5);
for(int i=;i<=m;++i)
if(!vis[i]) for(int j=i*i;j<=;j+=i) vis[j]=;
//筛选结束
for(int i = ; i <= ; ++i){
int rt = /i;
for(int j = i; j <= rt; ++j){
if(vis[i]){//非质数
++ans[i*j];
}
if(vis[j] && i!=j){
++ans[i*j];
}
}
}
}
int main()
{
init();
int Q;
scanf("%d",&Q);
while(Q--)
{
int n;
scanf("%d",&n);
printf("%d\n",ans[n]);
}
return ;
}

L - Non-Prime Factors (质数筛选+因子分解)的更多相关文章

  1. PAT 1059. Prime Factors (25) 质因子分解

    题目链接 http://www.patest.cn/contests/pat-a-practise/1059 Given any positive integer N, you are suppose ...

  2. POJ2689 Prime Distance 质数筛选

    题目大意 求区间[L, R]中距离最大和最小的两对相邻质数.R<2^31, R-L<1e6. 总体思路 本题数据很大.求sqrt(R)的所有质数,用这些质数乘以j, j+1, j+2... ...

  3. [CareerCup] 7.7 The Number with Only Prime Factors 只有质数因子的数字

    7.7 Design an algorithm to find the kth number such that the only prime factors are 3,5, and 7. 这道题跟 ...

  4. ZOJ 1842 Prime Distance(素数筛选法2次使用)

    Prime Distance Time Limit: 2 Seconds      Memory Limit: 65536 KB The branch of mathematics called nu ...

  5. POJ2689 - Prime Distance(素数筛选)

    题目大意 给定两个数L和U,要求你求出在区间[L, U] 内所有素数中,相邻两个素数差值最小的两个素数C1和C2以及相邻两个素数差值最大的两个素数D1和D2,并且L-U<1,000,000 题解 ...

  6. 2014辽宁ACM省赛 Prime Factors

    问题 L: Prime Factors 时间限制: 1 Sec  内存限制: 128 MB [提交][状态][论坛] 题目描写叙述 I'll give you a number , please te ...

  7. PAT 甲级 1059 Prime Factors (25 分) ((新学)快速质因数分解,注意1=1)

    1059 Prime Factors (25 分)   Given any positive integer N, you are supposed to find all of its prime ...

  8. PAT Advanced 1059 Prime Factors (25) [素数表的建⽴]

    题目 Given any positive integer N, you are supposed to find all of its prime factors, and write them i ...

  9. PAT-1059 Prime Factors (素数因子)

    1059. Prime Factors Given any positive integer N, you are supposed to find all of its prime factors, ...

随机推荐

  1. Unity 利用UGUI打包图集,动态加载sprite资源

    今天做了一个UI界面,这个界面是好友界面,该界面上有若干个好友item. 需要对每个tem的头像对象(image)动态显示对应的头像.尝试利用UGUI的图集来加载,具体实现如下: 1.首先,需要知道S ...

  2. laravel中get()与 first()区别、collection与stdClass的区别

    简单的,laravel里get()得到的是一组数据,first()得到的是一个model数据. 从形式上,laravel里每一个model数据(record),在取出的时候都是用的PHP的stdCla ...

  3. 微信公众平台开发教程(一)_微信接入校验以及token获取

    微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,而公众平台开发接口则是提供服务的基础. 接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 ...

  4. Unity3D判断当前所在平台

    Unity3D是一个跨平台的开发工具,支持的平台五花八门,常常开发一款游戏要发布到不同的平台,在不同的平台上会使用不同的代码,难道要我们各平台分别使用一套代码,单独编译一次吗?当然不用了,呵呵.    ...

  5. OpenStack-Neutron-Fwaas-代码【二】

    上一节从代码层面来讲解了fwaas的流程,这里通过具体查看iptables规则来说下应用规则的流程: 1.首先通过命令获取当前路由中的规则 #ip netns exec qrouter-[router ...

  6. ubuntu18.04 安装pip3

    Ubuntu18.04默认内嵌python2.python3,pip安装时,python2对应安装pip,python3对应安装pip3. sudo apt install python3-pip 检 ...

  7. python精进之路1---基础数据类型

    python精进之路1---基本数据类型 python的基本数据类型如上图,重点需要掌握字符串.列表和字典. 一.int.float类型 int主要是用于整数类型计算,float主要用于小数. int ...

  8. Aes CBC加密

    <?php namespace app\components; use yii; class Aes { /** * This was AES-128 / CBC / PKCS5Padding ...

  9. 【转】jenkins+gitlab配置遇到问题

    搭建jenkins+gitlab拉取代码失败,日志如下: ERROR: Error fetching remote repo 'origin'hudson.plugins.git.GitExcepti ...

  10. 日志入库-log4j-mysql连接中断问题

    mysql5.6 druid1.0.17 log4j 1.2.16 一定时间后无法连接  CommunicationsException: Communications link failure 粗暴 ...