更新...最后发现根本不用在循环中判断是否是素数, 因为先除的肯定是素数, 后面的以该素数的倍数组成的合数早就被除没了.....
//新的build() 注意最后一位的处理
void build(){ int sq = sqrt(ori); int i; for (i = 2; i <= sq + 1; ++i) { // if( (i<50000 and isPrime(i)) or(i>=50000)){ bool ok = false; while(todo % i == 0){ ok = true; todo = todo / i; n[len]++; } if(ok){ primeNums[len] = i; len++; } } if(todo>=sq+1){ primeNums[len] = todo; n[len]++; len++; } }
///早期的sb代码
虽然是水题,但是被坑了n多次...一开始超时..以为是判断素数的效率问题, 后来用了生成素数表的方法, 变成了RE 这才知道不是这个问题.
注意到数据范围是在2^31内的, 根据Hint可知 大于 sqrt(a)的a的质因数只有一个.
那么对于一个很大的数, 那个很大的质因数肯定就是它自己,就不要对其进行判断了.
生成素数表的代码如下:
void generatePrimes(){ memset(bePrime,true,sizeof(bePrime)); bePrime[2] = true; for (int i = 2; i < 50000;i++) { if(!bePrime[i]){ for (int j = 2*i; j < 50000; j+=i) bePrime[j] = false; } } }
主要思想是先假设所有的数都是素数,然后把每一个素数的所有倍数都判否(注意要顺序)就可以了,但是实际上对于效率的提升貌似不高。。。。
核心代码很简单, 需要注意的是那个神奇的if条件, 完美的避开了这个问题...
void build(){ for (int i = 2; i <= todo; ++i) { if( (i<50000 and isPrime(i)) or(i>=50000)){ bool ok = false; while(todo % i == 0){ ok = true; todo = todo / i; n[len]++; } if(ok){ primeNums[len] = i; len++; if(i*i>ori){ break; } } } } }