Description
已知phi(N),求N。
Input
两个正整数,分别表示phi(N)和K。
phi(N)<=10^14,K<=1000
Output
按升序输出满足条件的最小的K个N。
Sample Input
8 4
Sample Output
15 16 20 24
HINT
传送门
看上去很神……其实式子写写就基本出来了。
假设n=p1^a1*p2^a2*……*pk^ak,
那么:
φ(n)=n*∏(1-1/pi)
根据这个,又我们已经知道了φ(n)
所以n=φ(n)*∏(pi/(pi-1))
观察这个式子:
因为pi都是素数,所以(pi-1)和pi互质的,那么因为n是整数,
所以(pi-1)都是φ(n)的约数
而且(pi-1)的乘积也是φ(n)的约数。
那么有一个比较简单的想法就是枚举所有φ(n)的约数
然后一一弄,
显然看上去时间复杂度等等有点点不可做。
那么提供一种方法:
首先线性筛出10^7内的所有素数,也就是给出的φ(n)的根号
然后进入一个dfs暴力找所有n的过程,能够YY出满足某一个φ(n) n的个数不会很多,
(后面发现了<50W个)
对于当前的φ(n),简便点用fi表示
那么首先当然是在所有筛出来的素数-1里面找有没有fi的约数,
如果有,假设它是x,那么除去fi里面的所有x,并且要求的n里面也得出现x,
暴力把x的个数累计上去做;
然后假如说fi>10^7,用Miller-Rabin判断(fi+1)是不是素数,
如果是,那么很明显直接得到了一个新的n;
就用这种方法不断取所有素数,具体过程用一个dfs实现。
考虑到时间等问题,素数的除去从大到小除去,那么会优化很多。
一开始各种地方写炸,还差点忘记miller-rabin怎么写……
竟然没什么题解……
后面发现一直WA的原因竟然是答案数组只开了1W……
暴力改了100W,然后又测了测50W都AC了。。
最重要的dfs的过程各种意义已经标注在代码里了,直接说有点说不清楚。