solution1(通过10%)
#include<stdio.h>
#include<math.h>
typedef long long LL;
int isPrime(LL n){LL sqr = (int)sqrt(1.0 * n);for(int i = 2; i <= sqr; i++){if(n % i == 0) return 0;}return 1;
}
int main(){int t;LL a;scanf("%d", &t);while(t--){LL f[100] = {0}, sqr, num = 0, odd = 0, even = 0, flag = 0;scanf("%lld", &a);if(isPrime(a)) flag = 1;else{sqr = (int)sqrt(1.0*a);for(int i = 2; i <= sqr; i++){if(a % i == 0){while(a % i == 0){a /= i;f[num]++;}if(f[num] == 1) {flag = 1;break;}else if(f[num] % 2 == 0) even++;else odd++; num++;}if(odd > 2 || (odd == 2 && even > 0)){flag = 1;break;}}if(a > 1) flag = 1;}if(flag) printf("no\n");else printf("yes\n");} return 0;
}
solution2
1 <= ai <= 1018,
奇数次幂可以分解为偶数次幂*奇数次幂
则能够拆分的数最后一定能分解为下列形式:
- a2*b3
==》至多有五次方,而上界1018开五次方大约是4000左右
#include<stdio.h>
#include<math.h>
int main(){printf("%lld", (long long)pow(1e18, 0.2));//3981return 0;
}
列出4000以内的素数,看是否有只出现一次的质因数,若有则一定不能拆分,木有人和它配对不满足指数大于等于2
分解后a等于1或者是大于4000的因子,这样一番分解后a不会太大了,直接判断是否能够分解为平方或者立方的形式融入其中即可
#include<stdio.h>
#include<math.h>
typedef long long LL;
LL p[4005] = {0}, prime[4005], n = 0;
int check(LL a){LL s, num;for(int i = 1; i <= n && prime[i] * prime[i] <= a; i++){num = 0;if(a % prime[i] == 0){while(a % prime[i] == 0){a /= prime[i];num++;}if(num == 1) return 0;}}s = sqrt(1.0 * a);while(s*s <= a){if(s*s == a) return 1;s++;}s = pow(a, 1.0 * 1 / 3);while(s*s*s <= a){if(s*s*s == a) return 1;s++;} return 0;
}
int main(){int t;LL a;scanf("%d", &t);for(int i = 2; i <= 4000; i++){if(!p[i]){prime[++n] = i;for(int j = i * i; j <= 4000; j += i){p[j] = 1;}}}while(t--){scanf("%lld", &a);if(check(a)) printf("yes\n");else printf("no\n");} return 0;
}