Observations: the sequence F(i) mod 100 is periodic (Pisano period). For modulus 100 the period divides 100*100=10000; in practice the period for modulus 100 is 300. That means F(n) mod 100 = F(n % 300) mod 100. We present three methods:
classSolution {
public:longlong fib_naive(unsignedlonglong n) {
if (n ==0) return0;
if (n ==1) return1;
longlong a =0, b =1;
for (unsignedlonglong i =2; i <= n; ++i) { longlong nxt = a + b; a = b; b = nxt; }
return b %100;
}
};
classSolutionMod100 {
public:int last_two(unsignedlonglong n) {
int a =0, b =1;
if (n ==0) return0;
for (unsignedlonglong i =1; i <= n; ++i) { int nxt = (a + b) %100; a = b; b = nxt; }
return a %100;
}
};
1
2
3
4
5
6
7
8
packagemainfuncLastTwoFib(nuint64) int {
a, b:=0, 1ifn==0 { return0 }
fori:= uint64(1); i<=n; i++ { a, b = b, (a+b) %100 }
returna%100}
1
2
3
4
5
6
7
8
classSolution {
publicintlastTwo(long n) {
int a = 0, b = 1;
if (n == 0) return 0;
for (long i = 1; i <= n; ++i) { int nxt = (a + b) % 100; a = b; b = nxt; }
return a % 100;
}
}
1
2
3
4
5
6
7
8
classSolution {
funlastTwo(n: Long): Int {
var a = 0; var b = 1if (n ==0L) return0for (i in1..n) { val nxt = (a + b) % 100; a = b; b = nxt }
return a % 100 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution:
deflast_two(self, n: int) -> int:
a, b =0, 1if n ==0:
return0for _ in range(1, n +1):
a, b = b, (a + b) %100return a %100deflast_two_str(self, s: str) -> int:
# reduce large decimal string n modulo 300 (Pisano period) r =0for ch in s:
r = (r*10+ (ord(ch) -48)) %300return self.last_two(r)
1
2
3
4
5
6
7
8
9
pubstructSolution;
impl Solution {
pubfnlast_two(mut n: u128) -> u8 {
if n ==0 { return0 }
let (mut a, mut b) = (0u8, 1u8);
for _ in1..=n { let nxt = ((a asu16+ b asu16) %100) asu8; a = b; b = nxt; }
a
}
}
The sequence F(i) mod 100 repeats with period 300. Therefore F(n) mod 100 = F(n % 300) mod 100. Compute idx = n % 300 (stream digits if n is a string) and then compute F(idx) mod 100.