在project euler 的第\(10\)题的 \(forum\) 中 Lucy Hedgehog 提到的这种方法。



### 求 $n$ 以内素数个数以及求 $n$ 以内素数和的算法。
### 定义$S(v,p)$为$2$ 到 $v$ 所有整数中,在普通筛法中外层循环筛完 $p$ 时仍然幸存的数的和。因此这些数要不本身是素数,要不其最小的素因子也大于 $p$ 。因此我们需要求的是 $S(n,\lfloor\sqrt n\rfloor)$。
### 为了计算 $S(v,p)$,先考虑几个特殊情况。


### $1.$ $p\le1$ 。此时所有数都还没有被筛掉,所以 $S(v,p)=\sum_{i=2}^{v}i=\frac{(2+v)(v-1)}{2}$。
### $2.$ $p$ 不是素数。因为筛法中 $p$ 早已被别的数筛掉,所以在这步什么都不会做,所以此时 $S(v,p)=S(v,p-1)$。
### $3.$ $p$ 是素数,但是 $v

### 现在考虑最后一种稍微麻烦些的情况:$p$ 是素数,且 $p^2\le v$。
### 此时,我们要用素数 $p$ 去筛掉剩下的那些数中 $p$ 的倍数。注意到现在还剩下的合数都没有小于 $p$ 的素因子。因此有:
### $S(v,p)=S(v,p-1)-\sum_{\substack{2\le k \le v,\\ p\mbox{为}k\mbox{的最小素因子}}}k$


### 后面那项中提取公共因子 $p$ ,有:
### $S(v,p)=S(v,p-1)-p\times\sum_{\substack{2\le k \le v,\\ p\mbox{为}k\mbox{的最小素因子}}}\frac{k}{p}$


### 因为 $p$ 整除 $k$ ,稍微变形一下,令 $t=\frac{k}{p}$,有:
### $S(v,p)=S(v,p-1)-p\times\sum_{\substack{2\le t \le \lfloor\frac{v}{p}\rfloor,\\ t\mbox{的最小素因子}\ge p}}t$


### 因为 $S$ 的定义s是(“这些数要不本身是素数,要不其最小的素因子也大于(注意!)$ p $”),此时 $p$ 后面这项可以用 $S$ 来表达。

\(S(v,p)=S(v,p-1)-p\times(S(\left\lfloor\frac{v}{p}\right\rfloor,p-1)-\{p-1\mbox{以内的所有素数和}\})\)



### 再用 $S$ 替换素数和得到最终表达式:
### $S(v,p)=S(v,p-1)-p\times(S(\left\lfloor\frac{v}{p}\right\rfloor,p-1)-S(p-1,p-1))$


### 我们最终的结果是 $S(n,\lfloor\sqrt n\rfloor)$。
### 这是求前 $n$ 的素数和的方法。
### 至于求前 $n$ 的素数个数的方法也差不多。
### 只需要把代码修改一下即可。

复杂度: \(O(n^{0.75})\)

C++代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll; ll check(ll v, ll n, ll ndr, ll nv) {
return v >= ndr ? (n / v - 1) : (nv - v);
} // ll S[10000000];
// ll V[10000000];
ll primenum(ll n) // O(n^(3/4))
{
ll r = (ll)sqrt(n);
ll ndr = n / r;
assert(r*r <= n && (r+1)*(r+1) > n);
ll nv = r + ndr - 1;
std::vector<ll> S(nv+1);
std::vector<ll> V(nv+1);
for(ll i=0;i<r;i++) {
V[i] = n / (i+1);
}
for(ll i=r;i<nv;i++) {
V[i] = V[i-1] - 1;
}
for(ll i = 0;i<nv;i++) {
S[i] = V[i] - 1; //求素数个数
}
for(ll p=2;p<=r;p++) {
if(S[nv-p] > S[nv-p+1]) {
ll sp = S[nv-p+1]; // sum of primes smaller than p
ll p2 = p*p;
// std::cout << "p=" << p << '\n'; // p is prime
for(ll i=0;i<nv;i++) {
if(V[i] >= p2) {
S[i] -= 1LL * (S[check(V[i] / p, n, ndr, nv)] - sp);// //求素数个数
}
else break;
}
}
}
return S[0];
}
ll primesum(ll n) // O(n^(3/4))
{
ll r = (ll)sqrt(n);
ll ndr = n / r;
assert(r*r <= n && (r+1)*(r+1) > n);
ll nv = r + ndr - 1;
std::vector<ll> S(nv+1);
std::vector<ll> V(nv+1);
for(ll i=0;i<r;i++) {
V[i] = n / (i+1);
}
for(ll i=r;i<nv;i++) {
V[i] = V[i-1] - 1;
}
for(ll i = 0;i<nv;i++) {
S[i] = V[i] * ( V[i] + 1) / 2 - 1; //求素数和
}
for(ll p=2;p<=r;p++) { // p is prime
if(S[nv-p] > S[nv-p+1]) {
ll sp = S[nv-p+1]; // sum of primes smaller than p
ll p2 = p*p;
for(ll i=0;i<nv;i++) {
if(V[i] >= p2) {
S[i] -= p* (S[check(V[i] / p, n, ndr, nv)] - sp); //求素数和
}
else break;
}
}
}
return S[0];
}
int main(int argc, char const *argv[]) {
// std::cout << primesum(1e6) << '\n';
std::cout << primenum(1e10) << '\n';
std::cout << primesum(2e6) << '\n';
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
return 0;
}

Lucy_Hedgehog techniques的更多相关文章

  1. Web Application Penetration Testing Local File Inclusion (LFI) Testing Techniques

    Web Application Penetration Testing Local File Inclusion (LFI) Testing Techniques Jan 04, 2017, Vers ...

  2. 新书到手 TRANSACTION PROCESSING:CONCEPTS AND TECHNIQUES

    新书到手 TRANSACTION PROCESSING:CONCEPTS AND TECHNIQUES Jim Gray大神的著作 本文版权归作者所有,未经作者同意不得转载.

  3. MATLAB 图像处理——Contrast Enhancement Techniques

    Contrast Enhancement Techniques %调整图片尺寸imresizeimages{k} = imresize(images{k},[width*dim(1)/dim(2) w ...

  4. Looping Techniques

    [Looping Techniques] 1.When looping through dictionaries, the key and corresponding value can be ret ...

  5. 39. Volume Rendering Techniques

    Milan Ikits University of Utah Joe Kniss University of Utah Aaron Lefohn University of California, D ...

  6. 7 Types of Regression Techniques you should know!

    翻译来自:http://news.csdn.net/article_preview.html?preview=1&reload=1&arcid=2825492 摘要:本文解释了回归分析 ...

  7. Beginners Guide To Learn Dimension Reduction Techniques

    Beginners Guide To Learn Dimension Reduction Techniques Introduction Brevity is the soul of wit This ...

  8. [翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data Access Techniques)

    Performance Comparison: Data Access Techniques Priya DhawanMicrosoft Developer Network January 2002 ...

  9. 小白日记45:kali渗透测试之Web渗透-SqlMap自动注入(三)-sqlmap参数详解-Optimization,Injection,Detection,Techniques,Fingerprint

    sqlmap自动注入 Optimization [优化性能参数,可提高效率] -o:指定前三个参数(--predict-output.--keep-alive.--null-connection) - ...

随机推荐

  1. 紫书 习题 10-22 UVa 10479 (找规律)

    自己一直在纠结这个串的构造方法 而没有观察串本身的规律-- 2的63次方用 unsigned long long 然后可以发现串是递归构造的. 将串分成1,1,2,4,8,16, 然后会发现s串里面1 ...

  2. 【Henu ACM Round #13 E】Spy Syndrome 2

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 对m个串建立一棵字典树. 然后对主串. 尝试从第一个位置开始.在字典树中尝试匹配 如果匹配到了位置i 就再从位置i+1开始尝试匹配 ...

  3. 聊聊高并发(十八)理解AtomicXXX.lazySet方法

    看过java.util.concurrent.atomic包里面各个AtomicXXX类实现的同学应该见过lazySet方法.比方AtomicBoolean类的lazySet方法 public fin ...

  4. h5播放音乐

    h5音频播放,里面參数能够查看http://www.w3school.com.cn/html5/html_5_audio.asp <audio controls="controls&q ...

  5. 手动连接数据库(jdbc)

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  6. 第二天,导出文件sql,查询,视图view,聚合函数,反模式,字符串处理函数

    //把数据库导出到脚本文件mysqldump -uroot -p1234 --databases abc > d:/a/abc.sql CREATE TABLE stud( id INT PRI ...

  7. 关于jquery点击之后,标签的hover失效这个问题

    做一个点击切换的效果,加在a标签上,jquery的click加上css中的hover 点击之后,css的hover效果就没有了,后来知道是click的权值比外联的css大 当点击之后,css代码就被覆 ...

  8. OpenCV —— 矩阵和图像操作

    cvAbs , cvAbsDiff , cvAbsDiffS cvAdd , cvAddS , cvAddWeighted(可添加权重) #include <cv.h> #include ...

  9. Android开源图表库XCL-Charts版本号公布及展示页

    XCL-Charts V2.1 Android开源图表库(XCL-Charts is a free charting library for Android platform.) XCL-Charts ...

  10. java初始化过程中成员变量

    package day01; class Base{ int j; //1.j=0 Base(){ add(1); //2.调用子类add()方法 System.out.println(j); //4 ...