根据上述规则,我们可以有如下递推公式
a
i
t
=
(
a
i
−
1
t
−
1
+
a
i
+
1
t
−
1
+
1
)
  
mod
  
2
,
if
i
>
0
  
a
n
d
  
i
<
m
−
1
a^t_i = (a^{t-1}_{i-1} + a^{t-1}_{i+1} + 1) \; \text{mod} \; 2, \quad \text{if} \quad i \gt 0 \; and \; i \lt m - 1
ait=(ai−1t−1+ai+1t−1+1)mod2,ifi>0andi<m−1
a
i
t
=
0
  
mod
  
2
,
if
i
=
0
  
o
r
  
i
=
m
−
1
a^t_i = 0 \; \text{mod} \; 2, \quad \text{if} \quad i = 0 \; or \; i = m - 1
ait=0mod2,ifi=0ori=m−1
根据这个递推公式,我们可以给出一个矩阵运算的递推式:
x
t
=
A
x
t
−
1
x^t = Ax^{t-1}
xt=Axt−1
其中
x
x
x是把
a
a
a变成一个列向量,并在最后加一维
1
1
1,所以
x
x
x是
m
+
1
m+1
m+1维的
A
A
A是
m
+
1
×
m
+
1
m+1 \times m+1
m+1×m+1维的矩阵,具体每维的值定义如下:
A
(
i
−
1
,
i
+
1
)
=
1
,
if
i
>
0
  
a
n
d
  
i
<
m
−
1
A
(
i
,
m
)
=
1
,
if
i
=
0
  
o
r
  
i
=
m
−
1
A
(
i
,
j
)
=
0
,
o
t
h
e
r
w
i
s
e
A(i-1, i+1) = 1, \quad \text{if} \quad i \gt 0 \; and \; i \lt m - 1\\ A(i, m) = 1, \quad \text{if} \quad i = 0 \; or \; i = m - 1\\ A(i, j) = 0, \quad otherwise
A(i−1,i+1)=1,ifi>0andi<m−1A(i,m)=1,ifi=0ori=m−1A(i,j)=0,otherwise
因此,
x
n
=
A
n
×
x
0
  
mod
  
2
x^n = A^n \times x^0 \; \text{mod} \; 2
xn=An×x0mod2, 然后我们可以利用矩阵快速幂进行求解了。
最后时间复杂度:
O
(
m
3
log
n
)
O(m^3 \log n)
O(m3logn)
实现1(循环节)
class Solution {
public:staticconstint NUM =8;voidto_vector(const bitset<NUM>& x, vector<int>& out){for(int i =0; i < NUM; i++){
out.push_back(x[i]);}}voidto_bitset(const vector<int>& x, bitset<NUM>& out){for(int i =0; i < x.size(); i++){
out[i]= x[i];}}
bitset<NUM>transfer(const bitset<NUM> st){
bitset<NUM> next;
next[0]=0;
next[NUM -1]=0;for(int i =1; i < NUM -1; i++){if(st[i-1]== st[i+1]){
next[i]=1;}else{
next[i]=0;}}return next;}
vector<int>prisonAfterNDays(vector<int>& cells,int N){
bitset<NUM> st;
unordered_map<bitset<NUM>,int> mapp;
unordered_map<int, bitset<NUM>> rmapp;to_bitset(cells, st);int len =-1, pre =-1;for(int i =0; i < N; i++){if(mapp.find(st)!= mapp.end()){int idx = mapp[st];
len = i - mapp[st];
pre = mapp[st];break;}
mapp[st]= i;
rmapp[i]= st;
st =transfer(st);}
vector<int> ans;if(len ==-1){to_vector(st, ans);return ans;}int now =(N - pre +1)% len;if(now ==0){to_vector(rmapp[pre + len -1], ans);return ans;}to_vector(rmapp[pre + now -1], ans);return ans;}};
实现2(矩阵快速幂)
class Solution {
public:staticconstint NUM =8;typedef vector<int> vec;typedef vector<vec> mat;
mat matmul(const mat& A,const mat& B){
mat C(A.size(),vec(B[0].size()));for(int i =0; i < A.size(); i++){for(int k =0; k < B.size(); k++){for(int j =0; j < B[0].size(); j++){
C[i][j]+= A[i][k]* B[k][j];
C[i][j]%=2;}}}return C;}
mat tomat(vec& A){
mat B(A.size(),vec(1));for(int i =0; i < A.size(); i++){
B[i][0]= A[i];}return B;}
mat matpow(const mat& A,int n){
mat ans(A.size(),vec(A[0].size(),0));for(int i =0; i < ans.size(); i++)
ans[i][i]=1;
mat tmp(A);while(n >0){if(n &1){
ans =matmul(ans, tmp);}
tmp =matmul(tmp, tmp);
n>>=1;}return ans;}
vector<int>prisonAfterNDays(vector<int>& cells,int N){
mat A(cells.size()+1,vec(cells.size()+1));*(A.rbegin()->rbegin())=1;for(int i =1; i < cells.size()-1; i++){
A[i][i-1]=1;
A[i][i+1]=1;*A[i].rbegin()=1;}
cells.push_back(1);auto x =tomat(cells);
A =matpow(A, N);
x =matmul(A, x);
vec ans;for(int i =0; i < cells.size()-1; i++){
ans.push_back(x[i][0]);}return ans;}};