• zzulioj 2623: 小H的作业题(素数筛选,打表)


    题目链接:http://acm.zzuli.edu.cn/problem.php?id=2623

      看到这题第一眼想到的打表,首先筛选出来1e6之内的素数,然后我们再对1e6之内的数求其每个素因子的最高幂次有没有是偶数的情况,当然这样直接做的话肯定会超时的,所以我们要优化一下,在这个数除以某个素因子之后,他肯定是比原来小的,由于我们是顺序打表,所以比这个数小的数的情况我们已经判断过了,所以直接利用就行了。
    #include<set>
    #include<map>
    #include<stack>
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<string>
    #include<vector>
    #include<climits>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define max(a, b) (a > b ? a : b)
    #define min(a, b) (a < b ? a : b)
    #define mst(a) memset(a, 0, sizeof(a))
    #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const double eps = 1e-7;
    const int INF = 0x3f3f3f3f;
    const ll ll_INF = 0x3f3f3f3f3f3f3f;
    const int maxn = 1e6+10;
    int prime[maxn];
    bool ok[maxn];
    void solve1() { //筛素数
        fill(prime, prime+maxn, 1);
        prime[0] = prime[1] = 0;
        int end = sqrt(maxn) + 0.5;
        for (int i = 2; i<=end; ++i)
            if (prime[i])
                for (int j = i*2; j<maxn; j+=i)
                    prime[j] = 0;
    }
    bool solve2(int n) {
        int t = n;
        if (prime[t]) //显然素数不行
            return false;
        for (int i = 2; i<t && n != 1; ++i) {
            int cnt = 0;
            if (prime[i]) { //计算素因子最高幂次
                while(!(n%i)) {
                    n /= i;
                    ++cnt;
                }
            }
            if ((!(cnt%2) && cnt)) //如果某个素因子最高幂次是偶数,那么符合要求
                return true;
            else if (n < t)
                return ok[n]; //n<t的情况我们已经算出来了,所以我们直接返回就是了
        }
        return false; 
    }
    int main(void) {
        solve1();
        for (int i = 1; i < maxn; ++i) //打表,方便下面O(1)查找
            ok[i] = solve2(i);
        int t;
        scanf("%d", &t);
        while(t--) {
            int n;
            scanf("%d", &n);
            printf(ok[n] ? "YES\n" : "NO\n");
        }
        return 0;
    }
  • 相关阅读:
    Redis学习笔记六:持久化实验(AOF,RDB)
    MySQL从源码编译安装
    Redis学习笔记五:缓存常见问题
    修复MySQL漏洞防火墙策略(CentOS7)
    Linux释放根目录空间(CentOS)
    CentOS7离线安装firewalld及端口配置
    Linux通过软链接方式对磁盘进行变相扩容
    SNMP及SNMP Trap对接指南
    Oracle安装磁盘空间满了怎么办?(Windows Server)
    无法打开OracleEnterpriseManager页面【http://localhost:1158/em】
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12078720.html
Copyright © 2020-2023  润新知