Məsələnin müəllifi: | Al_Kaosar |
Hazırlayan: | MathModel |
Redaktə edən: | MathModel |
Həll
Məqsəd x, y \ge 1 üçün f(x, y) = |n - x^y| + |x - y| ifadəsini minimum etməkdir.
Sabit üçün x^y qiymətini -ə ən yaxın edən ya \lfloor n^{1/y} \rfloor, ya da \lceil n^{1/y} \rceil olur. n \le 10^{18} olduğuna görə, əgər x \ge 2-dirsə, onda ən çox təxminən ola bilər, çünki 2^{60} > 10^{18}. Əgər x=1 olarsa, ifadə |n-1| + |1-y| şəklini alır və bu da y=1 olduqda minimum olur, nəticə isə n-1 edir.
Biz -nin bütün mümkün qiymətlərini -dən -yə qədər yoxlaya bilərik. Hər bir üçün x \approx n^{1/y} qiymətini təxmin edirik. n=10^{18} üçün üzən nöqtəli hesablamalarda dəqiqlik problemləri yarana biləcəyindən, -i pow(n, 1/y) ilə tapıb onun ətrafında kiçik bir aralığı yoxlamaq, yaxud x^y \le n şərtini ödəyən -i tapmaq üçün ikili axtarışdan istifadə etmək daha təhlükəsizdir.
Hər bir y \in [1, 62] üçün x_{cand} \in \{\lfloor n^{1/y} \rfloor, \lceil n^{1/y} \rceil\} namizədlərini yoxlayırıq. Həmçinin x=y namizədini də yoxlayırıq, çünki bu halda ifadənin ikinci hissəsi sıfır olur.
Ümumi mürəkkəblik O(\log n)-dir.
def solve():
n=int(input())
ans=n-1
K=n.bit_length()
for y in range(2,K+1):
r=int(n**(1/y))
for x in(r,r+1):
if x>0:
p=pow(x,y)
ans=min(ans,abs(n-p)+abs(x-y))
print(ans)
for _ in range(int(input())):
solve()