[数学][大整数质因数分解] codeforces1033D Divisors

思路简单,就是求出来结果的所有质因数的指数+1乘起来就行了。

首先由于题目的要求这里读入的ai只有两种情况,要么ai=p*q是两个不相等素数的乘积,要么ai=p^k,其中k取2,3,4。显然后一种情况很容易处理,但是第一种就有些难受了,直接的想法是用一些优秀的O(N^(1/4))的非完美大整数分解算法(这个看tutorial的评论区神仙各有千秋)。但是由于第一类的数只能分解成两个质因数,而且我们最后要的是质因数的指数而不需要关心质因数本身是多少,所以就有了更好的策略:如果一个数字的质因数在其他数字中出现过,那么一定可以通过gcd求出来,这时候等于说另一个质因数直接一除也能求出来,等于这个ai就完全解决了,像第二种情况一样加到map里即可;如果说这个数的俩质因数都没有在其他数字中出现过那么我们肯定不能求出来这俩数字是多少了,但是我们可以知道出现了俩独特的质因数,他出现且仅出现在所有aj==ai里,那么我们可以把ai直接存进map里,存起来他对应的加了多少次,另外要单独开一个set记录下来哪些ai是这样的ai,最后计算的时候如果是这样的ai的话就乘以(1+map值)的平方就可以了。

所以说一定要分析所给数据的性质,他的约束是解题的难点但同时也可能是解题的突破口。
写的时候还有一点弄错了就是把哥德巴赫猜想和这个搞混了。。那个是+这个是*,而且哥德巴赫猜想在1e18的范围内一定是有一个小的和一个大的,这个小的不超过1e5好像,所以那个是只需要枚举小的然后判断大的是否为质数即可。

继续阅读“[数学][大整数质因数分解] codeforces1033D Divisors”

[学习] 线性筛+预处理+遍历/分解质因子

写这个是还是从今天那个C题目来的。看正解的时候发现了他用了一个很神奇的遍历质因子的方法,没有多余的操作,就是完全的遍历每一个质因子,只不过需要预先用线性筛处理出来1到n的每一个数字的最小质因子。感觉适用于需要分解多个数字质因子的情况但是我自己写的暴力sqrt(n)貌似也不慢多少就很迷。。。emmmmmm不管了先记下来再说。

继续阅读“[学习] 线性筛+预处理+遍历/分解质因子”

[数学][质因数分解][预处理优化] codeforces 1034A Enlarge GCD

http://codeforces.com/problemset/problem/1034/A

题意问给定n个数,从中最少去掉多少个数之后可以使得剩下的数字的gcd严格大于原序列的gcd。

思路:先求出来原序列的gcd,无解的情况很容易判断,当序列中最大的数字就是gcd的时候无解。对于有解的情况,把每个数字除以这个gcd,剩下的一个序列就是gcd为1的序列,然后只要求出来去掉多少个数字之后可以使得序列gcd不为1就行了。这时候考虑去掉k个数字之后剩下的数字gcd为几,不妨设为w,很容易知道如果能求出来对于每个质数有多少个数字有这个质因子,那么取“在序列中出现最多次数的那个质数”的出现次数就是最大的剩下的序列中的元素个数,这里的出现次数是说如果ai%w==0则cnt++的意思。那么能求出来剩下的元素最多有多少个,也就能求出来去除的元素最少有多少个了。

比赛时候这个题是把我T爆了,主要是很难确定对于每个数暴力质因数分解好还是线性筛预处理出来1.5e7之内的素数比较好,一开始一直用的暴力质因数分解但是test23一直t,最后6min换了预处理素数ac了,其实手推渐进复杂度感觉二者差不多。。。。玄学卡常,而且最后过了也是800ms飘过。。。

继续阅读“[数学][质因数分解][预处理优化] codeforces 1034A Enlarge GCD”