3713: [PA2014]Iloczyn

时间:2021-06-05 04:09:12

3713: [PA2014]Iloczyn

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 327  Solved: 181
[Submit][Status][Discuss]

Description

斐波那契数列的定义为:k=0或1时,F[k]=k;k>1时,F[k]=F[k-1]+F[k-2]。数列的开头几项为0,1,1,2,3,5,8,13,21,34,55,…你的任务是判断给定的数字能否被表示成两个斐波那契数的乘积。

Input

第一行包含一个整数t(1<=t<=10),表示询问数量。接下来t行,每行一个整数n_i(0<=n_i<=10^9)。

Output

输出共t行,第i行为TAK(是)或NIE(否),表示n_i能否被表示成两个斐波那契数的乘积。

Sample Input

5
5
4
12
11
10

Sample Output

TAK
TAK
NIE
NIE
TAK

HINT

 

Source

鸣谢Jcvb

题解:一开始我还想着怎么预处理,但是后来发现貌似也就\( \log M \)个数字(虽然显然没这么少,但实际上也就不超过60个的样子)在\( {10}^{9} \)一下,然后\( T \leq 10 \),暴力枚举轻松水过(PS:呵呵呵逗比的我还用了个平衡树来维护,但后来才想到貌似二分查找就够了= =)

 /**************************************************************
Problem:
User: HansBug
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ var
a:array[..] of int64;
lef,rig,fix:array[..] of longint;
i,j,k,l,m,n,head,t:longint;
a1:int64;
procedure rt(var x:longint);
var f,l:longint;
begin
if (x=) or (lef[x]=) then exit;
f:=x;l:=lef[x];
lef[f]:=rig[l];
rig[l]:=f;
x:=l;
end;
procedure lt(var x:longint);
var f,r:longint;
begin
if (x=) or (rig[x]=) then exit;
f:=x;r:=rig[x];
rig[f]:=lef[r];
lef[r]:=f;
x:=r;
end;
procedure ins(var x:longint;y:longint);
begin
if x= then
begin
x:=y;
exit;
end;
if a[y]<=a[x] then
begin
if lef[x]= then lef[x]:=y else ins(lef[x],y);
if fix[lef[x]]<fix[x] then rt(x);
end
else
begin
if rig[x]= then rig[x]:=y else ins(rig[x],y);
if fix[rig[x]]<fix[x] then lt(x);
end;
end;
function check(x:longint;y:int64):boolean;
begin
if x= then exit(false);
if a[x]=y then exit(true);
if y<a[x] then exit(check(lef[x],y)) else exit(check(rig[x],y));
end;
begin
a[]:=;a[]:=;head:=;randomize;
for i:= to do a[i]:=a[i-]+a[i-];
for i:= to do
begin
lef[i]:=;rig[i]:=;fix[i]:=random(maxlongint);
ins(head,i);
end;
readln(t);
while t> do
begin
readln(a1);
if a1= then writeln('TAK') else
begin
j:=;
for i:= to do
begin
if a[i]>a1 then break;
if (a1 mod a[i])<> then continue;
if check(head,a1 div a[i]) then
begin
j:=;writeln('TAK');
break;
end;
end;
if j= then writeln('NIE');
end;
dec(t);
end;
readln;
end.