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. 请求http页面的相关过程

    http请求从TCP建立三次握手后进行,客户端按照规定的格式向服务器发送http请求,服务器在接收到这个请求之后,首先要对其进行解析,发掘出客户端所需要的相关资源,然后经过相应的业务逻辑处理,找到这个 ...

  2. Python语言——基础02-变量、运算符

    开篇导言: 今天开始进行python学习的笔记更新,以后我都用截图的方式更新,方便不麻烦,界面美观,今天学习更新的python学习内容是环境变量.运算符的内容 关注我博客的童鞋从现在开始也可以跟着我的 ...

  3. 从网卡发送数据再谈TCP/IP协议—网络传输速度计算-网卡构造

    在<在深谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP>里面提到 单个TCP包每次打包1448字节的数据进行发送(以太网Ethernet最大的数据帧是1518字节,以 ...

  4. 【数据结构】算法 LinkList (Remove Nth Node From End of List)

    删除链表中倒数第n个节点 时间复杂度要控制在O(n)Solution:设置2个指针,一个用于确定删除节点的位置,一个用于计算倒数间距n.移动时保持2个指针同时移动. public ListNode r ...

  5. LR参数化取值规则总结

    我想使用参数化输入设置10个并发用户循环1000次,第一个用户使用参数列表中的前1000个参数(第依次循环使用第一个参数.第二次循环使用第二个参数,依次类推).第二个用户使用参数列表中的2001-30 ...

  6. Keepalived配置文件详解

    global_defs { router_id LVS_$prio #节点唯一标识,通常为hostname } local_address_group laddr_g1 { ${lvs_node} # ...

  7. vue获得当前页面URL动态拼接URL复制邀请链接方法

    vue获得当前页面URL动态拼接URL复制邀请链接方法 当前页面完整url可以用 location.href路由路径可以用 this.$route.path路由路径参数 this.$route.par ...

  8. Docker 构建 RabbitMQ 集群

    刚开始,关于RabbitMQ集群的搭建,我找到了这篇文章:Docker 安装 RabbitMQ 集群 从而找到了第三方的RabbitMQ集群容器 rabbitmq-server 但是这个容器只有3.6 ...

  9. Py 最全的常用正则表达式大全 ZZ

    很多不太懂正则的朋友,在遇到需要用正则校验数据时,往往是在网上去找很久,结果找来的还是不很符合要求.所以我最近把开发中常用的一些正则表达式整理了一下,在这里分享一下.给自己留个底,也给朋友们做个参考. ...

  10. 与TIME_WAIT相关的几个内核参数

    问题 公司用浏览器访问线上服务一会失败一会成功,通过ssh连接服务器排查时发现ssh也是这样: 检查 抓包后发现建立连接的请求已经到了服务器,但它没有响应: 纠结了好久,后来在腾讯云技术支持及查了相关 ...