Time Limit: 2000 ms Memory Limit: 512 MB

Description

  给定 \(n\), 求\(\sum\limits_{p,q∈primes}[pq≤n]\)

  (其中 primes 表示全体质数组成的集合)

  (其中 [expression] 当 expression 为真时值为 \(1\), 否则为 \(0\))

Input

  一行一个数 \(n\)

Output

  一行一个数表示答案

Sample Input

sample 1:
1
sample 2:
5
sample 3:
10

Sample Output

sample 1:
0
sample 2:
1
sample 3:
6

HINT

  对于 20% 的数据, \(1≤n≤10^8\)

  对于 100% 的数据 , \(1≤n≤10^{11}\)


Solution

  (所以为什么学长强行出了一道科普性质的题啊qwq被科普到了qwq)

  • 20%

  线性筛爆搞一下就好了

  • 100%

  于是乎这里就科普了一种十分神秘的筛法了qwq

  首先先想想怎么去求我们的\(ans\)

  用\(pcnt(i)\)表示小于等于\(i\)的素数的个数,用\(cnt\)表示小于等于\(\sqrt{n}\)的素数的个数,\(P\)为素数列表,那么

\[ans=(2*\sum\limits_{i=1}^{cnt}pcnt(\lfloor \frac{n}{P_i}\rfloor)-i)+cnt
\]

  具体一点的话就是,如果两个素数\(p\)和\(q\)的乘积小于等于\(n\),那么这两个素数中必定有一个小于等于\(\sqrt{n}\),所以我们只要枚举小于等于\(\sqrt{n}\)的那个素数然后把\(pcnt(\lfloor\frac{n}{p}\rfloor)\)累加起来最后乘个\(2\)就好了,然而由于这样在枚举的时候会重复,所以我们钦定每个素数只算与大于它的素数相乘的贡献,因此要减掉\(i\)(也就是前面小于p的数中有多少个素数),最后再加上自己乘自己的\(cnt\)种情况就好了

  

  那么现在的问题就是要求\(pcnt(i)\),我们先不考虑空间的问题

  考虑把\(pcnt(i)\)筛出来,大致思路如下:

    1.去掉既不是合数也不是素数的\(1\)

    2.去掉小于等于i的合数

  去掉\(1\)的话就是初始化\(pcnt(i)=i-1\),这个比较好搞

  去掉合数的话,我们考虑用每个素数\(p\)去筛掉\(i>p\)的\(pcnt(i)\)中的一些数

  考虑每个\(p\)能够筛掉的部分,应该是形如\(p*k\ (k\in [2,\lfloor \frac{i}{p} \rfloor])\)的

  而因为我们是从小到大一直用不同的素数去筛,所以到用\(p\)筛的时候,\(pcnt(i)\)中包含的数的最小质因子应该是大于等于\(p\)的,所以\(p\)能够筛掉的部分,实际上应该是形如\(的最小质因子p*k\ (k的最小质因子>=p)\),也就是说实际上真正能够被\(p\)筛掉数的\(i\)应该满足:\(i>=p^2\)

  再考虑一下当前那些还没有被完全筛成正确答案的\(pcnt(x)\)具有什么性质:

    1.\(x>p\)

    2.\(pcnt(x)\)由两部分组成,对于小于\(p\)的部分,所有的合数已经被筛完了,而大于\(p\)的部分,仅有最小 质因子\(>=p\)的数

    也就是说\(pcnt(x)\)=小于\(p\)的素数个数 + \(p\)到\(x\)中最小质因子\(>=p\)的数的个数

    

  然后回去看对于\(pcnt(i)\)来说\(p\)能够筛掉的数,我们会发现其实上面提到的\(k\)的个数其实就是\(pcnt(\lfloor \frac{i}{p}\rfloor)-pcnt(p-1)\)

  具体一点的话就是:

  (因为只有对于\(i>=p^2\)的\(pcnt(i)\),\(p\)才能筛掉数,所以接下来讨论的\(pcnt(i)\)都默认\(i>=p^2\))

  因为\(i>=p^2\),所以\(\lfloor \frac{i}{p}\rfloor>=p\)

  对于大于的情况,\(pcnt(\lfloor \frac{i}{p}\rfloor)=小于p的素数个数+p到\lfloor \frac{i}{p}\rfloor中的最小质因子>=p的数的个数\)

  那么\(k\)的个数就是\(pcnt(\lfloor \frac{i}{p}\rfloor)-pcnt(p-1)\)(\(pcnt(p-1)\)已经被筛好了)

  对于等于的情况,能去掉的只有\(p^2\),此时\(pcnt(\lfloor \frac{i}{p}\rfloor)=pcnt(p)\), 相减一下得到\(1\),也是成立的

  

  综上,筛掉合数我们要做的就是:

  用每个素数去筛,对于每个\(i>=p^2\),从\(pcnt(i)\)减去\(pcnt(\lfloor \frac{i}{p}\rfloor)-pcnt(p-1)\)即可

  至于素数,其实也不用预处理什么的,只要判断\(pcnt(i)\)与\(pcnt(i-1)\)是否相等即可,不等说明\(i\)是素数

  

  然而现在的问题是,空间开不了这么大啊

  我们考虑将\(pcnt(i)\)分成两部分:

  \(p1(i)=pcnt(i)\)和\(p2(i)=pcnt(\lfloor \frac{n}{i}\rfloor)\),\(i\in[1,\sqrt{n}]\)

  \(p1(i)\)的话直接算就好了

  \(p2(i)\)的话,考虑用\(p\)来筛的情况,我们套回上面的式子稍微化一下得到:

\[\begin{aligned}
p2(i)&=pcnt(\lfloor \frac{n}{i}\rfloor)\\
&=pcnt(\lfloor \frac{n}{i}\rfloor)-(pcnt(\lfloor \frac{\lfloor \frac{n}{i}\rfloor}{p}\rfloor)-pcnt(p-1))\\
&=pcnt(\lfloor \frac{n}{i}\rfloor)-(pcnt(\lfloor \frac{n}{i*p}\rfloor))-pcnt(p-1))\\
\end{aligned}
\]

  考虑\(\lfloor \frac{n}{i*p}\rfloor\)的取值,如果说这个值小于等于\(\sqrt{n}\)那么\(pcnt(\lfloor \frac{n}{i*p}\rfloor)=p1(\lfloor \frac{n}{i*p}\rfloor)\),否则\(pcnt(\lfloor \frac{n}{i*p}\rfloor)=p2(i*p)\)

  那就直接在枚举的时候判断一下就好了

  注意最后统计\(ans\)的时候因为我们要调用的是\(()pcnt(\lfloor \frac{n}{P_i}\rfloor)(\lfloor \frac{n}{P_i}\rfloor>=\sqrt{n})\),所以应该是用\(p2(\lfloor \frac{n}{\lfloor \frac{n}{P_i}\rfloor}\rfloor)\)

  

  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int MAXN=1e6+10;
ll p1[MAXN],p2[MAXN],lis[MAXN];
ll n,m,sq,ans,cnt; int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%lld",&n);
sq=sqrt(n);
for (int p=2;p<=sq;++p) p2[p]=n/p-1,p1[p]=p-1;
for (ll p=2;p<=sq;++p)
if (p1[p]!=p1[p-1]){
lis[++cnt]=p;
for (ll i=1;i<=sq&&1LL*p*p<=n/i;++i){
if (n/(1LL*p*i)>sq)
p2[i]-=p2[p*i]-p1[p-1];
else
p2[i]-=p1[n/(1LL*p*i)]-p1[p-1];
}
for (int i=sq;i>=p*p;--i){
p1[i]-=p1[i/p]-p1[p-1];
}
}
ans=0;
for (int i=1;i<=cnt;++i)
ans+=p2[n/(n/lis[i])]-i;
printf("%lld\n",ans*2+cnt);
}

pxp的更多相关文章

  1. ListView初探

    一.ListView介绍 在Android开发中ListView是比较常用的控件,常用于以列表的形式显示数据集及根据数据的长度自适应显示. ListView通常有两个主要功能点: (1)将数据集填充到 ...

  2. java web学习总结(三十一) -------------------EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  3. 【krpano】krpano xml资源解密(破解)软件说明与下载(v1.4)

    欢迎加入qq群551278936讨论krpano技术以及获取最新软件.   该软件已经不再维护,现在已经被KRPano资源分析工具取代,详情参见 http://www.cnblogs.com/reac ...

  4. mysql深入浅出的笔记(存储过程二)

    1.条件的定义和处理可以用来定义在处理过程中遇到问题时相应的处理步揍: DECLARE condition_name CONDITION FOR condition_value condition_v ...

  5. 【CQgame】[幸运方块 v1.1.2] [Lucky_Block v1.1.2]

    搬家首发!!! 其实从初一我就写过一些小型战斗的游戏,但是画面都太粗糙,代码也比较乱,也就是和两三个同学瞎玩,但自从观摩了PoPoQQQ大神的游戏,顿时产生了重新写一部游戏的冲动,于是各种上网查找各种 ...

  6. 浅谈ThinkPHP3.2的子域名部署和路由优化(一)

    前言:建立一个网站系统,往往包含多个子网站,例如PC官网,移动端官网,后台管理,数据源自一个相同的数据库,整个架构上,从ThinkPHP来看,可以大体理解为Model(M)是一样的,Controlle ...

  7. 3.Java网络编程之IP

    前面两篇博文我们已经简单了解了IP.端口.协议以及两种参考模型,我们现在重新从程序角度来看下这个参考模型. 如果我们从事的是Web网站开发,那么我们应该知道HTML是一种超文本标记语言 (Hyper ...

  8. 1.Java基础之System对象

    毕向东老师Java基础学习笔记——System对象 今天学习Java中的System对象后,感觉这个对象对我们主要有以下几点用处. 1.获取当前操作系统版本和类型. 2.获取当前操作系统的path中的 ...

  9. C++ 基础知识复习(五)

    UML建模部分 70. 什么是UML: 答: Unified Modeling Language, 统一建模语言,是一种标准的图形化建模语言.是面向对象分析和设计的标准表示. 71. UML有哪些图: ...

随机推荐

  1. Jmeter接口测试(三)接口测试实践

    Jmeter 脚本编写一般分五个步骤: 1. 添加线程组 2. 添加 http 请求 3. 在 http 请求中写入接入 url.路径.请求方式和参数 4. 添加查看结果树 5. 调用接口.查看返回值 ...

  2. Lua学习笔记(7): 模块

    模块 模块就像是c语言工程项目目录里的.h.c文件或外部依赖项,为某一个文件的代码提供依赖,其实就是把工作分成几个模块,方便项目的管理,提高开发效率和维护效率 在Lua中,模块其实就是一个表,实现方式 ...

  3. Lua学习笔记(3):运算符

    算术运算符 运算符 描述 + 加法运算符 - 减法运算符 * 乘法运算符 / 除法运算符 % 取模运算符 ^ 乘幂 A=3 print(A^2)输出9 关系运算符 ~= 不等于 == 等于 > ...

  4. PaaSoo云通讯-印度市场机遇与挑战并存

    2019年4月16日,由白鲸出海举办的2019中印互联网大会(Global Connects India)在印度新德里举行,这次的大会主要涵盖了出海主题峰会.B2B展会.中印互联网高层圆桌等模块. 众 ...

  5. 第六次ScrumMeeting博客

    第六次ScrumMeeting博客 本次会议于10月31日(二)22时整在3公寓725房间召开,持续15分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕.方科栋. 除了汇报任务外,窦鑫泽同学还就前 ...

  6. 用 Python 3 的 async / await 做异步编程

    前年我曾写过一篇<初探 Python 3 的异步 IO 编程>,当时只是初步接触了一下 yield from 语法和 asyncio 标准库.前些日子我在 V2EX 看到一篇<为什么 ...

  7. 线段树---成段更新hdu1698 Just a Hook

    hdu1698 Just a Hook 题意:O(-1) 思路:O(-1) 线段树功能:update:成段替换 (由于只query一次总区间,所以可以直接输出1结点的信息) 题意:给一组棍子染色,不同 ...

  8. c#程序的阅读

    1 .程序是为表示两个连续的整数不能被整除. 2 ,3 程序黑框得不出结果,所以不知道具体的结果和运行时间. 4 采用更好的专用电脑进行计算.

  9. Varnish是一款高性能的开源HTTP加速器

    如何衡量缓存系统的优劣性 1:缓存命中率: 在memcached服务器中,get_hits的值表示缓存命中的次数,get_misses的值表示没有命中的次数,那么命中率的计算公式就是:命中率=get_ ...

  10. Scrum 项目准备3.0

    SCRUM 流程的步骤2: Spring 计划 1. 确保product backlog井然有序.(参考示例图1) 2. Sprint周期,一个冲刺周期,长度定为两周,本学期还有三个冲刺周期. Spr ...