// Calculate Nth Fibbionacci number in O(log N)
// Matrix multiplication
def matmul
( mat1
: Array
[ Array
[ Int
] ] , mat2
: Array
[ Array
[ Int
] ] ) : Array
[ Array
[ Int
] ] = { var res
= new Array
[ Array
[ Int
] ] ( n, n
) ; res( i) ( j) = 0 ;
res( i) ( j) += mat1( i) ( k) * mat2( k) ( j) ;
}
}
}
}
// Matrix powering
def matpow
( mat
: Array
[ Array
[ Int
] ] , pow
: Int
) : Array
[ Array
[ Int
] ] = { var par, res
= new Array
[ Array
[ Int
] ] ( n, n
) ; par( i) ( j) = mat( i) ( j) ;
if ( i
== j
) res
( i
) ( j
) = 1 ; }
}
res = matmul( res, par) ;
}
par = matmul( par, par) ;
}
}
// Calculate sum of a
def fibb
( n
: Int
) : Int
= { var mat
= new Array
[ Array
[ Int
] ] ( 2 ,
2 ) ; mat( 0 ) ( 0 ) = 1 ; mat( 0 ) ( 1 ) = 1 ; mat( 1 ) ( 0 ) = 1 ; mat( 1 ) ( 1 ) = 0 ;
mat = matpow( mat, n) ;
}
// Main function
def main
( args
: Array
[ String
] ) = { Scanner in
= new Scanner
( System.
in ) ; for ( i
< -
0 until n
) println
( fibb
( num
) ) ; }
}
Ly8gQ2FsY3VsYXRlIE50aCBGaWJiaW9uYWNjaSBudW1iZXIgaW4gTyhsb2cgTikKaW1wb3J0IGphdmEudXRpbC5TY2FubmVyOwpvYmplY3QgTWFpbnsKCS8vIE1hdHJpeCBtdWx0aXBsaWNhdGlvbgoJZGVmIG1hdG11bChtYXQxIDogQXJyYXlbIEFycmF5IFtJbnRdIF0sIG1hdDIgOiBBcnJheVsgQXJyYXkgW0ludF0gXSk6IEFycmF5WyBBcnJheSBbSW50XSBdID0gewoJCXZhbCBuID0gbWF0MS5zaXplOwoJCXZhciByZXMgPSBuZXcgQXJyYXlbIEFycmF5IFtJbnRdXShuLCBuKTsKCQlmb3IoaSA8LSAwIHVudGlsIG4pewoJCQlmb3IoaiA8LSAwIHVudGlsIG4pewoJCQkJcmVzKGkpKGopID0gMDsKCQkJCWZvcihrIDwtIDAgdW50aWwgbil7CgkJCQkJcmVzKGkpKGopICs9IG1hdDEoaSkoaykgKiBtYXQyKGspKGopOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiByZXM7Cgl9CgkvLyBNYXRyaXggcG93ZXJpbmcKCWRlZiBtYXRwb3cobWF0IDogQXJyYXlbIEFycmF5IFtJbnRdIF0sIHBvdyA6IEludCk6IEFycmF5WyBBcnJheSBbSW50XSBdID0gewoJCXZhbCBuID0gbWF0LnNpemU7CgkJdmFyIHBhciwgcmVzID0gbmV3IEFycmF5WyBBcnJheSBbSW50XV0obiwgbik7CgkJZm9yKGkgPC0gMCB1bnRpbCBuKXsKCQkJZm9yKGogPC0gMCB1bnRpbCBuKXsKCQkJCXBhcihpKShqKSA9IG1hdChpKShqKTsKCQkJCWlmKGkgPT0gaikgcmVzKGkpKGopID0gMTsKCQkJCWVsc2UgcmVzKGkpKGopID0gMDsKCQkJfQoJCX0KCQl3aGlsZShwb3cgPiAwKXsKCQkJaWYocG93ICUgMiA9PSAxKXsKCQkJCXJlcyA9IG1hdG11bChyZXMsIHBhcik7CgkJCX0KCQkJcGFyID0gbWF0bXVsKHBhciwgcGFyKTsKCQl9CgkJcmV0dXJuIHJlczsKCX0KCS8vIENhbGN1bGF0ZSBzdW0gb2YgYQoJZGVmIGZpYmIobiA6IEludCk6IEludCA9IHsKCQl2YXIgbWF0ID0gbmV3IEFycmF5WyBBcnJheSBbSW50XV0oMiwgMik7CgkJbWF0KDApKDApID0gMTsgbWF0KDApKDEpID0gMTsgbWF0KDEpKDApID0gMTsgbWF0KDEpKDEpID0gMDsKCQltYXQgPSBtYXRwb3cobWF0LCBuKTsKCQlyZXR1cm4gbWF0KDEpKDApOwoJfQoJLy8gTWFpbiBmdW5jdGlvbgoJZGVmIG1haW4oYXJncyA6IEFycmF5WyBTdHJpbmcgXSkgPSB7CgkJU2Nhbm5lciBpbiA9IG5ldyBTY2FubmVyKFN5c3RlbS5pbik7CgkJdmFsIG51bSA9IGluLm5leHRJbnQoKTsKCQlmb3IoIGkgPC0gMCB1bnRpbCBuKSBwcmludGxuKGZpYmIobnVtKSk7Cgl9Cn0K