1+ const MOD : i64 = 1000000007 ;
2+
3+ impl Solution {
4+ pub fn num_of_ways ( n : i32 ) -> i32 {
5+ if n == 1 {
6+ return 12 ;
7+ }
8+ let mut available = vec ! [ ] ;
9+ for i in 1 ..64usize {
10+ let c1 = i & 3 ;
11+ let c2 = ( i>>2 ) & 3 ;
12+ let c3 = ( i>>4 ) & 3 ;
13+ if c1 !=0 && c2 != 0 && c3 != 0 && c3 != c2 && c2 != c1 {
14+ available. push ( i) ;
15+ }
16+ }
17+ assert_eq ! ( 12 , available. len( ) ) ;
18+ let mut count = [ 0 ; 64 ] ;
19+ for & v in & available {
20+ count[ v as usize ] = 1i64 ;
21+ }
22+ for _ in 1 ..n {
23+ let mut new_count = [ 0 ; 64 ] ;
24+ for & pre_color in & available {
25+ let num = count[ pre_color] ;
26+ if num == 0 {
27+ continue ;
28+ }
29+ let c1 = pre_color & 3 ;
30+ let c2 = ( pre_color>>2 ) & 3 ;
31+ let c3 = ( pre_color>>4 ) & 3 ;
32+ for & color in & available {
33+ let t1 = color & 3 ;
34+ let t2 = ( color>>2 ) & 3 ;
35+ let t3 = ( color>>4 ) & 3 ;
36+ if t1 != c1 && t2 != c2 && t3 != c3 {
37+ new_count[ color] += num;
38+ new_count[ color] %= MOD ;
39+ }
40+ }
41+ }
42+ count = new_count;
43+ }
44+ ( ( count. iter ( ) . sum :: < i64 > ( ) ) % MOD ) as i32
45+ }
46+ pub fn num_of_ways_mat ( n : i32 ) -> i32 {
47+ if n == 1 {
48+ return 12 ;
49+ }
50+ let ( ( a, b) , ( c, d) ) = Self :: mat_pow ( ( ( 3 , 2 ) , ( 2 , 2 ) ) , n as usize -1 ) ;
51+ ( ( 6 * ( a+b+c+d) ) % MOD ) as i32
52+ }
53+ fn mat_pow ( mat : ( ( i64 , i64 ) , ( i64 , i64 ) ) , n : usize ) -> ( ( i64 , i64 ) , ( i64 , i64 ) ) {
54+ if n == 1 {
55+ return mat;
56+ }
57+ let t = n / 2 ;
58+ let q= Self :: mat_pow ( mat, t) ;
59+ let w = Self :: mat_mul ( q, q) ;
60+ if n & 1 == 1 {
61+ Self :: mat_mul ( w, mat)
62+ } else {
63+ w
64+ }
65+ }
66+ fn mat_mul ( x : ( ( i64 , i64 ) , ( i64 , i64 ) ) , y : ( ( i64 , i64 ) , ( i64 , i64 ) ) ) -> ( ( i64 , i64 ) , ( i64 , i64 ) ) {
67+ let ( ( x11, x12) , ( x21, x22) ) = x;
68+ let ( ( y11, y12) , ( y21, y22) ) = y;
69+ let z11 = ( x11* y11+x12* y21) % MOD ;
70+ let z12 = ( x11* y12+x12* y22) % MOD ;
71+ let z21 = ( x21* y11+x22* y21) % MOD ;
72+ let z22 = ( x21* y21+x22* y22) % MOD ;
73+ ( ( z11, z12) , ( z21, z22) )
74+ }
75+ }
76+
77+ struct Solution ;
78+
79+ #[ cfg( test) ]
80+ mod tests {
81+ use super :: Solution ;
82+
83+ #[ test]
84+ fn test_num_of_ways ( ) {
85+ let test_cases = vec ! [
86+ ( 2 , 54 ) ,
87+ ( 3 , 246 ) ,
88+ ( 7 , 106494 ) ,
89+ ( 5000 , 30228214 ) ,
90+ ] ;
91+ for ( n, expect) in test_cases {
92+ //assert_eq!(Solution::num_of_ways(n), expect, "n:{}", n);
93+ assert_eq ! ( Solution :: num_of_ways_mat( n) , expect, "mat, n: {}" , n) ;
94+ }
95+ }
96+ }
0 commit comments