题目
https://jzoj.net/senior/#contest/show/2008/3
小结
我们知道φ(x)=x*(1-
1p1
)*(1-
1p2
)….(1-
1pn
)
所以反过来推,y=(
pqi−1
)*(pi-1)
于是,我们就先把y所有约数找出来,若某约数+1是个质数那么把它存到a数组里,
然后递归 x1表示当前x值,y1表示当前y值
每到一个x,要枚举次方数ei,x1*
(a[x]+1)k
,y1*
(a[x]+1)k−1
*a[x],当y1=y时,就判断s1是否比ans更优。
以上的式子就是上面的变形。
但是~会~超时
主要优化:
1、a从大到小排序会快很多
2、当前x1>=ans时退出
3、y mod y1>0时退出(比如说y=2*3*3*5,若s2=2*3*3*3,那么显然不行)
var
t,i,j:longint;
min,n:int64;
a:array[0..6720]of int64;
procedure kp(l,r:longint);
var
i,j,mid,t:int64;
begin
i:=l;
j:=r;
mid:=a[(i+j) div 2];
repeat
while a[i]>mid do inc(i);
while a[j]<mid do dec(j);
if i<=j then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if l<j then kp(l,j);
if i<r then kp(i,r);
end;
procedure dg(t:longint;x,y:int64);
var
ei,i:longint;
x1,y1:int64;
begin
if y=n then
begin
if min>x then min:=x;
exit;
end;
if t>a[0] then exit;
dg(t+1,x,y);
x1:=x*(a[t]+1);
y1:=y*a[t];
while n mod y1=0 do
begin
dg(t+1,x1,y1);
x1:=x1*(a[t]+1);
y1:=y1*(a[t]+1);
if x1>=min then break;
end;
end;
function ss(n:int64):boolean;
var
i:longint;
begin
for i:=2 to trunc(sqrt(n)) do
if n mod i=0 then exit(false);
exit(true);
end;
begin
readln(t);
for i:=1 to t do
begin
readln(n);
a[0]:=0;
min:=1 shl 62;
for j:=1 to trunc(sqrt(n)) do
if n mod j=0 then
begin
if ss(j+1) then
begin
inc(a[0]);
a[a[0]]:=j;
end;
if (j<>n div j)and(ss(n div j+1)) then
begin
inc(a[0]);
a[a[0]]:=n div j;
end;
end;
kp(1,a[0]);
dg(1,1,1);
writeln(min);
end;
end.