HDU 3826 Squarefree number ( 唯一分解定理 )
题意 : 给出一个数、问其能不能被任何一个平方数整除、如果可以则输出 No 即不是 Square-free Number 、否则输出 Yes
分析 :
首先 N 有 1e18 那么大、不能暴力
根据唯一分解定理、任何数可以分解成若干素数乘积形式
N = p1^a1 + p2^a2 + p3^a3 .....
那么可以利用这个特性来解决这个问题
首先可以知道其素因子肯定是不超过 1e6 的
那么对于 1e6 以内的素数我们先预处理出来
然后开始枚举、如果 N 能被两个或以上相同的素数整除的话
那么就说明其有平方因子
不过这个还不全面、对于 1e6 内的素数全部分解完了之后
如果 N 还是一个 > 1e6 的数、且它还包含平方因子的话
那么肯定是两个平方因子相乘的形式
直接开根验证即可
#include<bits/stdc++.h> #define LL long long #define ULL unsigned long long #define scl(i) scanf("%lld", &i) #define scll(i, j) scanf("%lld %lld", &i, &j) #define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k) #define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l) #define scs(i) scanf("%s", i) #define sci(i) scanf("%d", &i) #define scd(i) scanf("%lf", &i) #define scIl(i) scanf("%I64d", &i) #define scii(i, j) scanf("%d %d", &i, &j) #define scdd(i, j) scanf("%lf %lf", &i, &j) #define scIll(i, j) scanf("%I64d %I64d", &i, &j) #define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k) #define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k) #define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k) #define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l) #define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l) #define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l) #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define lowbit(i) (i & (-i)) #define mem(i, j) memset(i, j, sizeof(i)) #define fir first #define sec second #define VI vector<int> #define ins(i) insert(i) #define pb(i) push_back(i) #define pii pair<int, int> #define VL vector<long long> #define mk(i, j) make_pair(i, j) #define all(i) i.begin(), i.end() #define pll pair<long long, long long> #define _TIME 0 #define _INPUT 0 #define _OUTPUT 0 clock_t START, END; void __stTIME(); void __enTIME(); void __IOPUT(); using namespace std; const int maxn = (int)1e6 + 10; bool isPrime[maxn]; int Prime[maxn]; int tot; inline void init() { tot = 0; LL i, j; mem(isPrime, true); for(i=2; i<maxn; i++){ if(isPrime[i]){ Prime[tot++] = i; for(j=i+i; j<maxn; j+=i){ isPrime[j] = false; } } } } bool Test(LL &N) { for(int i=0; i<tot; i++){ if(N == 0) return false; if(N%Prime[i] == 0){ N /= Prime[i]; if(N > 0 && N%Prime[i] == 0) return true; } } return false; } int main(void){__stTIME();__IOPUT(); init(); int nCase, Case = 0; sci(nCase); while(nCase--){ LL N; scl(N); printf("Case %d: ", ++Case); if(Test(N)) puts("No"); else{ if(N > (LL)1e6){ bool Yes = true; LL num = (LL)sqrt((double)N); for(LL i=num-10; i<=num+10; i++){ if(i * i == N){ Yes = false; break; } } if(Yes) puts("Yes"); else puts("No"); }else puts("Yes"); } } __enTIME();return 0;} void __stTIME() { #if _TIME START = clock(); #endif } void __enTIME() { #if _TIME END = clock(); cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl; #endif } void __IOPUT() { #if _INPUT freopen("in.txt", "r", stdin); #endif #if _OUTPUT freopen("out.txt", "w", stdout); #endif }