// 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);
pow /= 2;
}
}
// 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
]) = { val in
= new Scanner
(System.
in); println(fibb(num));
}
}
Ly8gQ2FsY3VsYXRlIE50aCBGaWJiaW9uYWNjaSBudW1iZXIgaW4gTyhsb2cgTikKaW1wb3J0IGphdmEudXRpbC5TY2FubmVyOwpvYmplY3QgTWFpbnsKCS8vIE1hdHJpeCBtdWx0aXBsaWNhdGlvbgoJZGVmIG1hdG11bChtYXQxIDogQXJyYXlbIEFycmF5IFtJbnRdIF0sIG1hdDIgOiBBcnJheVsgQXJyYXkgW0ludF0gXSk6IEFycmF5WyBBcnJheSBbSW50XSBdID0gewoJCXZhbCBuID0gbWF0MS5zaXplOwoJCXZhciByZXMgPSBuZXcgQXJyYXlbIEFycmF5IFtJbnRdXShuLCBuKTsKCQlmb3IoaSA8LSAwIHVudGlsIG4pewoJCQlmb3IoaiA8LSAwIHVudGlsIG4pewoJCQkJcmVzKGkpKGopID0gMDsKCQkJCWZvcihrIDwtIDAgdW50aWwgbil7CgkJCQkJcmVzKGkpKGopICs9IG1hdDEoaSkoaykgKiBtYXQyKGspKGopOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiByZXM7Cgl9CgkvLyBNYXRyaXggcG93ZXJpbmcKCWRlZiBtYXRwb3cobWF0IDogQXJyYXlbIEFycmF5IFtJbnRdIF0sIHBvdyA6IEludCk6IEFycmF5WyBBcnJheSBbSW50XSBdID0gewoJCXZhbCBuID0gbWF0LnNpemU7CgkJdmFyIHBhciwgcmVzID0gbmV3IEFycmF5WyBBcnJheSBbSW50XV0obiwgbik7CgkJZm9yKGkgPC0gMCB1bnRpbCBuKXsKCQkJZm9yKGogPC0gMCB1bnRpbCBuKXsKCQkJCXBhcihpKShqKSA9IG1hdChpKShqKTsKCQkJCWlmKGkgPT0gaikgcmVzKGkpKGopID0gMTsKCQkJCWVsc2UgcmVzKGkpKGopID0gMDsKCQkJfQoJCX0KCQl3aGlsZShwb3cgPiAwKXsKCQkJaWYocG93ICUgMiA9PSAxKXsKCQkJCXJlcyA9IG1hdG11bChyZXMsIHBhcik7CgkJCX0KCQkJcGFyID0gbWF0bXVsKHBhciwgcGFyKTsKCQkJcG93IC89IDI7CgkJfQoJCXJldHVybiByZXM7Cgl9CgkvLyBDYWxjdWxhdGUgc3VtIG9mIGEKCWRlZiBmaWJiKG4gOiBJbnQpOiBJbnQgPSB7CgkJdmFyIG1hdCA9IG5ldyBBcnJheVsgQXJyYXkgW0ludF1dKDIsIDIpOwoJCW1hdCgwKSgwKSA9IDE7IG1hdCgwKSgxKSA9IDE7IG1hdCgxKSgwKSA9IDE7IG1hdCgxKSgxKSA9IDA7CgkJbWF0ID0gbWF0cG93KG1hdCwgbik7CgkJcmV0dXJuIG1hdCgxKSgwKTsKCX0KCS8vIE1haW4gZnVuY3Rpb24KCWRlZiBtYWluKGFyZ3MgOiBBcnJheVsgU3RyaW5nIF0pID0gewoJCXZhbCBpbiA9IG5ldyBTY2FubmVyKFN5c3RlbS5pbik7CgkJdmFsIG51bSA9IGluLm5leHRJbnQoKTsKCQlwcmludGxuKGZpYmIobnVtKSk7Cgl9Cn0K