题目链接:http://acm.zzuli.edu.cn/problem.php?id=2623
题目描述
期末考试即将来临,同学们都积极的在图书馆复习。今天小H也来到图书馆复习,小H掏出C语言课本,发现课本里还夹着一道老师出的作业题,小H想以此作业作为复习的开始,怎奈人生不如意,小H不能如愿写出这道作业题,你能帮助小H写出这道作业题吗?
已知算术基本定理描述如下:任何一个大于1的自然数N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=P1a1 × P2a2 × P3a3 × ...... × Pnan,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。
整数分解是密码学中的一个重要内容,现在给你一个整数,让你判断其是否存在素因子的最大幂次为偶数?例如18=21 × 32,存在一个素数3的幂次是2。
已知算术基本定理描述如下:任何一个大于1的自然数N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=P1a1 × P2a2 × P3a3 × ...... × Pnan,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。
整数分解是密码学中的一个重要内容,现在给你一个整数,让你判断其是否存在素因子的最大幂次为偶数?例如18=21 × 32,存在一个素数3的幂次是2。
输入
第一行输入t,代表输入组数 (0<t<=1000000)
第2~t+1行,输入一个整数n.(0<n<=1000000)
第2~t+1行,输入一个整数n.(0<n<=1000000)
输出
如果满足其因子含有某个整数的偶数次方,则输出“YES”(不含引号),否则输出"NO"(不含引号)
样例输入
Copy
3
18
24
360
样例输出
Copy
YES
NO
YES
提示
18=21×32 存在3的最大幂次是偶数
24=23×31 不存在最大素数的幂次是偶数
360=23×32×51 存在3的最大幂次是偶数
24=23×31 不存在最大素数的幂次是偶数
360=23×32×51 存在3的最大幂次是偶数
看到这题第一眼想到的打表+优化,首先筛选出来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; }