题目传送门

sol1:普通判到sqrt(n)的素数判定,不多说了。

  • 素数判定

    #include "bits/stdc++.h"
    using namespace std;
    bool is_prime(int n) {
    for (int i = ; 1LL * i * i <= n; i++)
    {
    if (n % i == ) return false;
    }
    return true;
    }
    int main() {
    int n, m;
    while (~scanf("%d", &n)) {
    int cnt = ;
    for (int i = ; i <= n; i++) {
    scanf("%d", &m);
    if (is_prime(m)) cnt++;
    }
    printf("%d\n", cnt);
    }
    return ;
    }

    复杂度sqrt(m),判断n次就是n * sqrt(m);

sol2:新get到的技巧Miller-Rabin素数测试,结合了费马小定理和二次探测定理,可以更高效的判断素数,存在误判可能,不过误判可能非常小,可以忽略不计;

  • Miller-Rabin素数测试

    #include "bits/stdc++.h"
    using namespace std;
    int quick_pow(int n, int k, int p) {
    int ans = ;
    while (k) {
    if (k & ) ans = 1LL * ans * n % p;
    n = 1LL * n * n % p;
    k >>= ;
    }
    return ans;
    }
    bool is_prime(int n) {
    // if (n < 2) return false;
    int s = , t = n - ;
    while (!(t & )) s++, t >>= ;
    for (int i = ; i <= ; i++) {
    int a = rand() % (n - ) + ;
    int k = quick_pow(a, t, n);
    for (int j = ; j <= s; j++) {
    int x = 1LL * k * k % n;
    if (x == && k != && k != n - ) return false;
    k = x;
    }
    if (k != ) return false;
    }
    return true;
    }
    int main() {
    int n, m;
    srand(time(NULL));
    while (~scanf("%d", &n)) {
    int cnt = ;
    for (int i = ; i <= n; i++) {
    scanf("%d", &m);
    if (is_prime(m)) cnt++;
    }
    printf("%d\n", cnt);
    }
    return ;
    }

    复杂度logm,判断n次就是n * log(m);

附加一个用于 LL 范围素数测试的模板:s

  • Miller-Rabin素数测试 LL 范围模板

    typedef long long LL;
    LL quick_mul(LL n, LL k, LL p) {
    LL ans = ;
    while (k) {
    if (k & ) ans = (ans + n) % p;
    n = (n + n) % p;
    k >>= ;
    }
    return ans;
    }
    LL quick_pow(LL n, LL k, LL p) {
    LL ans = ;
    while (k) {
    if (k & ) ans = quick_mul(ans, n, p);
    n = quick_mul(n, n, p);
    k >>= ;
    }
    return ans;
    }
    bool is_prime(LL n) {
    if (n < ) return false;
    LL s = , t = n - ;
    while (!(t & )) s++, t >>= ;
    for (int i = ; i <= ; i++) {
    LL a = rand() % (n - ) + ;
    LL k = quick_pow(a, t, n);
    for (int j = ; j <= s; j++) {
    LL x = quick_mul(k, k, n);
    if (x == && k != && k != n - ) return false;
    k = x;
    }
    if (k != ) return false;
    }
    return true;
    }

    大致差不多,为了防止爆 LL 加了一个快速积用于乘, 所以复杂度变成了log(m) * log(m)

最新文章

  1. Redis数据库
  2. ASP.NET MVC 视图(一)
  3. MySQL 专用备份软件参考
  4. javaweb学习总结(三十二)——JDBC学习入门
  5. 数据库sqlserver2008登陆名密码登陆不了怎么办?
  6. C#窗体钉在桌面、置底、嵌入桌面的办法
  7. JSON结构
  8. Linux下移植pjsip,使用QT开发
  9. 跳转界面方法 (runtime实用篇一)
  10. 【转】Android源码下载过程的一些注意事项
  11. MFC中菜单变灰的问题
  12. C语言博客作业一二维数组
  13. Gradle sync failed: SSL peer shut down incorrectly
  14. TR069网管测试华为ITMS平台(内部测试使用)
  15. Hbase学习03
  16. Metasploit
  17. 【Android】ScaleAnimation 详解
  18. Centos6.8 编译安装Apache2.4
  19. Termux 一款安卓终端模拟器
  20. centos7 设置静态IP

热门文章

  1. 吴裕雄--天生自然 JAVASCRIPT开发学习:弹窗
  2. Python笔记_第四篇_高阶编程_正则表达式_2.正则表达式入门
  3. idtcp实现文件下载和上传
  4. texshop 使用技巧
  5. windows 安装Bitcoin Core使用
  6. MyBatis从入门到精通(第5章):5.4 Example 介绍
  7. Tkinter控件Canvas
  8. 通过OAuth2.0 获取授权访问SF 用户数据
  9. no.2淘宝架构背后——零售业务中台架构设计探讨及实践读后感
  10. D. New Year and Conference(区间交,线段树)