hdu 5901 Count primes
题意:
计数区间$[1, n](1 \leq n \leq 10^{11})$素数个数。
分析:
这里只介绍一种动态规划的做法。
首先要说一下【分层思想】在动态规划中非常重要,下面的做法也正是基于这一思想。
我们用$dp[i]$表示区间$[1, \frac{n}{i}]$中素数的个数,用$c[i]$表示区间$[1, i]$中素数个数。
那么我们要求的即是$dp[1]$。由于$n$最大是$10^{11}$,因此任何区间内合数的最小素因子不超过$\sqrt{10^{11}}$。为了筛选素数,只需从区间内全体整数逐步划去最小素因子分别为$2, 3, 5, ...,$的和数即可。因此我们首先从小到大枚举素数$i$。
把$dp[i]$和这样的一个集合对应起来:当枚举到素数$i$时,$dp[i]$对应集合$DP(i)$,$DP(i)$是区间$[1, \frac{n}{i}]$划去所有包含不超过$i$的素因子的数后得到的集合,$dp[i]$为集合$DP(i)$的阶(长度)。考虑在加入素数$i$后更新$dp[j]$:
$dp[j] := dp[j] - (dp[i * j] - c[i - 1]) (*)$
注意到$DP(i * j)$和$DP(j)$的前面一部分是相同的,$DP(i * j)$即区间$[1, \frac{n}{i * j}]$经划去所有包含小于$i$素因子合数后得到的集合,它当然包含所有小于$i$的素数。因此
$dp[i * j] - c[i - 1]$中恰好包含了我们更新$dp[j]$时全部需要划去的元素,注意一点,这里$dp[i * j]$与$c[n / i / j]$与$c[n / (i * j)]$是等效的(因为$j$在内层循环逐增时,当且仅当$(i * j) | n$时对应到整数位置)。
因为我们枚举最小素因子$i$,同时保证$n / i / j \geq i - 1$因此控制外层循环$i \leq \sqrt{n} AND n / i / j \geq i - 1$
对于内层循环$j$,仅仅更新那些以后会用到的,这里保证在用到式 $(*)$时,$i * j \leq \sqrt{n}$, 因此$j \leq \sqrt{n}$
当$i * j > \sqrt{n}$时,使用式$dp[j] := dp[j] - (c[n / i / j] - c[i - 1])$替换上面的状态转移方程。
为此可以保证$dp[]$和$c[]$空间均为$O(\sqrt{n})$。
再考虑对$c[]$的更新:
$c[j] := c[j] - (c[j / i] - c[i - 1]) \text{ case }j / i \geq i - 1$
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <ctime>
#include <functional>
#include <cmath>
#include <iostream>
#include <assert.h>
#pragma comment(linker, "/STACK:102400000,102400000")
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define mp std :: make_pair
#define st first
#define nd second
#define keyn (root->ch[1]->ch[0])
#define lson (u << 1)
#define rson (u << 1 | 1)
#define pii std :: pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define type(x) __typeof(x.begin())
#define foreach(i, j) for(type(j)i = j.begin(); i != j.end(); i++)
#define FOR(i, s, t) for(int i = (s); i <= (t); i++)
#define ROF(i, t, s) for(int i = (t); i >= (s); i--)
#define dbg(x) std::cout << x << std::endl
#define dbg2(x, y) std::cout << x << " " << y << std::endl
#define clr(x, i) memset(x, (i), sizeof(x))
#define maximize(x, y) x = max((x), (y))
#define minimize(x, y) x = min((x), (y))
using namespace std;
typedef long long ll;
const int int_inf = 0x3f3f3f3f;
const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
const int INT_INF = (int)((1ll << ) - );
const double double_inf = 1e30;
const double eps = 1e-;
typedef unsigned long long ul;
typedef unsigned int ui;
inline int readint() {
int x;
scanf("%d", &x);
return x;
}
inline int readstr(char *s) {
scanf("%s", s);
return strlen(s);
} class cmpt {
public:
bool operator () (const int &x, const int &y) const {
return x > y;
}
}; int Rand(int x, int o) {
//if o set, return [1, x], else return [0, x - 1]
if (!x) return ;
int tem = (int)((double)rand() / RAND_MAX * x) % x;
return o ? tem + : tem;
}
ll ll_rand(ll x, int o) {
if (!x) return ;
ll tem = (ll)((double)rand() / RAND_MAX * x) % x;
return o ? tem + : tem;
} void data_gen() {
srand(time());
freopen("in.txt", "w", stdout);
int kases = ;
//printf("%d\n", kases);
while (kases--) {
ll sz = ;
printf("%d\n", sz);
FOR(i, , sz) {
int o = Rand(, );
int O = Rand(, );
putchar(O + (o ? 'a' : 'A'));
}
putchar('\n');
}
} const int maxn = 4e5 + ;
int c[maxn];
ll dp[maxn];
ll n; ll solve() {
int mid = (int)sqrt(n + .);
FOR(i, , mid) dp[i] = n / i - , c[i] = i - ;
for (int i = ; i <= mid; i++) {
if (c[i] == c[i - ]) continue;
for (int j = ; j <= mid && n / i / j >= i - ; j++) {
if (j <= mid / i) dp[j] -= dp[i * j] - c[i - ];
else dp[j] -= c[n / i / j] - c[i - ];
}
ROF(j, mid, ) {
if (j / i < i - ) break;
c[j] -= c[j / i] - c[i - ];
}
}
return dp[];
} int main() {
//data_gen(); return 0;
//C(); return 0;
int debug = ;
if (debug) freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
while (~scanf("%lld", &n)) {
ll ans = solve();
printf("%lld\n", ans);
}
return ;
}
hdu 5901 Count primes的更多相关文章
- HDU 5901 Count primes 论文题
Count primes 题目连接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5901 Description Easy question! C ...
- HDU 5901 Count primes( Meisell-Lehmer算法模板 )
链接:传送门 题意:计算 [ 1 , n ] 之间素数的个数,(1 <= n <= 1e11) 思路:Meisell-Lehmer算法是计算超大范围内素数个数的一种算法,原理并不明白,由于 ...
- hdu 5901 Count primes (meisell-Lehmer)
Count primes Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- HDU 5901 Count primes (2016 acm 沈阳网络赛)
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5901 题意:输入n,输出n以内质数个数 模板题,模板我看不懂,只是存代码用. 官方题解链接:https ...
- HDU 5901 Count primes (1e11内的素数个数) -2016 ICPC沈阳赛区网络赛
题目链接 题意:求[1,n]有多少个素数,1<=n<=10^11.时限为6000ms. 官方题解:一个模板题, 具体方法参考wiki或者Four Divisors. 题解:给出两种代码. ...
- hdu 5901 Count primes 素数计数模板
转自:http://blog.csdn.net/chaiwenjun000/article/details/52589457 计从1到n的素数个数 两个模板 时间复杂度O(n^(3/4)) #incl ...
- [素数个数模板] HDU 5901 Count primes
#include<cstdio> #include<cmath> using namespace std; #define LL long long ; bool np[N]; ...
- HDU 5901 Count primes 大素数计数
题意:计算1~N间素数的个数(N<=1e11) 题解:题目要求很简单,作为论文题,模板有两种 \(O(n^\frac{3}{4} )\),另一种lehmer\(O(n^\frac{2}{3})\ ...
- HDU 5901 Count primes (模板题)
题意:给求 1 - n 区间内的素数个数,n <= 1e11. 析:模板题. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024 ...
随机推荐
- 贪吃蛇的java代码分析(二)
代码剖析 贪吃蛇是一款十分经典的小游戏,对初入coding的朋友来说,拿贪吃蛇这样一个案例来练手十分合适,并不高的难度和成功后的成就感都是学习所必须的.下面我将依照我当时的思路,来逐步分析实现的整个过 ...
- 谈谈对Spring IOC的理解【转】
学习过Spring框架的人 一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大 ...
- shell -vim
编辑文件 vim vim 1.txt 点击i进入编辑模式 如果发现按上下左右有问题的且出现乱码的话,可能是编码格式不对导致的,在crt或者是xshell设置一下编码格式就行. 保存是点击ecs先退到预 ...
- matlab直方图均衡,使用向量优化
matlab自带有histeq函数对图像进行直方图均衡 自己写了一个,改成向量化形式,效率提高了一点,但是比自带的还是差很多,差不多9倍 function D = my_histeq(I) [m,n] ...
- rbd cache (一)
cache 1.why The existence of cache is based on a mismatch between the performance characteristics of ...
- C#读取Excel表格数据到DataGridView中和导出DataGridView中的数据到Excel
其实想在datagridview中显示excel表格中的数据跟读取数据库中的数据没什么差别,只不过是创建数据库连接的时候连接字段稍有差别. private void btnShow_Click(obj ...
- [原创]java WEB学习笔记109:Spring学习---spring中事物管理
博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好 ...
- Android tween 动画 XML 梳理
前言: Tween动画是展现出旋转.渐变.移动.缩放的这么一种转换过程,即补间动画.Tween动画有两种定义方式:XML形式,编码形式.这次主要来梳理XML的方式配置动画 (1)XML定义动画,按照动 ...
- 引用iScroll.js实现上拉和下拖刷新
使用技巧 1.引用iScroll.js, 在初始化时添加两个事件监听:touchMove.DOMContentLoaded. 2.实现iScroll插件的onScrollEnd事件, 也就是在这个事件 ...
- MAC下彻底解决mysql无法插入和显示中文
一.场景呈现 Mac 下Eclipse+mysql开发j2ee的时候,在页面像数据库中插入中文数据的时候,数据库会报错.而且即使插入成功,在控制台或者其他可视化数据库操作软件看数据发现都是??,错误的 ...