一个数字用斐波那契数列是唯一分解的,然后这个数列增长更快一些,那么要么是唯一分解,要么就无法分解,通过使用java大数发现到f[f[29]]的时候就已经超过10^(1e6)了。那么只要求这28个数就行了。
在比赛的时候我先用c++写暴力,发现要一分钟多才能预处理完,但是java的BigInteger几乎是秒出,但是后期一直在讲话,浪费了很多时间,然后最后才发要按照字典序最小的答案输出,就没时间处理了。
后来处理了,结果超时了,然而本机明明是秒出的。。。最后改成矩阵快速幂就过了。
import java.lang.reflect.Array;
import java.util.*;
import java.math.*;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class Main
{
public static BigInteger[][] multi(BigInteger [][]a,BigInteger [][]b)
{
BigInteger [][]c= new BigInteger[3][3];
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
c[i][j]=BigInteger.ZERO;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++) {
c[i][k] = c[i][k].add(a[i][j].multiply(b[j][k]));
}
return c;
}
public static BigInteger qp(int b)
{
BigInteger ans[][]=new BigInteger[3][3];
BigInteger cnt[][]=new BigInteger[3][3];
ans[1][1]=BigInteger.ONE;ans[1][2]=BigInteger.ZERO;
ans[2][1]=BigInteger.ZERO;ans[2][2]=BigInteger.ONE;
cnt[1][1]=BigInteger.ZERO;cnt[1][2]=BigInteger.ONE;
cnt[2][1]=BigInteger.ONE;cnt[2][2]=BigInteger.ONE;
while(b>0)
{
if(b%2==1)
ans=multi(ans,cnt);
cnt=multi(cnt,cnt);
b>>=1;
}
return ans[2][2];
}
public static void main(String args[])
{
int []f=new int [100];
int []ans=new int[100];
int up=0,cnt=3;
f[1]=1;f[2]=1;
for(int i=3;i<=28;i++)
f[i] = f[i - 2] + f[i - 1];
//PrintStream ps=new PrintStream("B.");
BigInteger []num=new BigInteger[30];
BigInteger a,b,w,sum=BigInteger.ZERO,tmp=BigInteger.ZERO;
a=BigInteger.ONE;
b=BigInteger.ONE;
num[1]=BigInteger.ONE;
num[2]=BigInteger.ONE;
num[3]=BigInteger.ONE;
Scanner input=new Scanner(System.in);
int id=0;
//System.out.println("a[1]=1;");
//System.out.println("a[2]=1;");
//System.out.println("a[3]=1;");
id=4;
for(int i=4;i<=28;i++)
num[i]=qp(f[i]-1);
int t,anscnt;
t=input.nextInt();
while(t>0)
{
t--;sum=BigInteger.ZERO;
w=input.nextBigInteger();
anscnt=0;
for(int i=28;i>=1;i--)
{
tmp=sum.add(num[i]);
if(tmp.compareTo(w)<=0) {
sum = tmp;
ans[++anscnt] = i;
}
}
if(sum.equals(w))
{
if(ans[anscnt]==5)
{
ans[anscnt]=1;ans[++anscnt]=2;ans[++anscnt]=3;
ans[++anscnt]=4;
}
else if(ans[anscnt]==4)
{
ans[anscnt]=1;
ans[++anscnt]=2;
}
else if(ans[anscnt]==3)
{
if(ans[anscnt-1]==4)
{
ans[anscnt-1]=3;
ans[anscnt]=1;
ans[++anscnt]=2;
}
else
ans[anscnt]=1;
}
else if(ans[anscnt]==2)
{
if(ans[anscnt-1]==3)
{
ans[anscnt - 1] = 1; ans[anscnt] = 2;
}
}
Arrays.sort(ans,1,anscnt+1);
for(int j=1;j<=anscnt;j++)
{
if(j>1)
System.out.print(" ");
System.out.print(ans[j]);
}
System.out.println("");
}
else
System.out.println("-1");
}
}
}