設f1
=f2=
f3=1
,fn=
fn−3
+fn−
1f1
=f2
=f3
=1,f
n=f
n−3
+fn−
1。求fnfn
。這篇部落格並不是專門來介紹矩陣乘法加速遞推的。
但是既然是模板題就提一下吧。
也就是說,對於兩個矩陣aa和b
b,在滿足第乙個矩陣的列數=第二個矩陣的行數
時,這兩個矩陣就可以相乘。那麼假設aa是m
×pm×
p的矩陣,bb是p
×np×
n的矩陣,那麼他們相乘得到的矩陣c
c就是乙個m×n
m×n的矩陣。
而且對於矩陣c
c的任意元素ij
ij,都等於矩陣a第i行的所有數字分別乘上矩陣b第j列的所有數字之和
。(其實就是上圖的公式)
矩陣乘法和遞推關係最密切的例子就是斐波那契數列了。↓矩陣
乘法求斐
波那契數
列矩陣乘
法求斐波
那契數列
現在看不懂沒關係,可以慢慢理解。
我們知道,斐波那契數列有這樣的定義:fi
=fi−
1+fi
−2fi
=fi
−1+
fi−2
那麼如果我們有乙個2×2
2×2的矩陣,其中第一行分別是fi−
1fi−
1和fi
−2fi
−2。我們的目標是把第一行承上乙個矩陣變成fif
i和fi
−1fi
−1。那麼應該怎麼辦呢?
首先,矩陣a
a和矩陣c
c都含有fi−
1fi−
1這一項。那麼就先從這裡下手。
我們知道,矩陣cc的f
i−1f
i−1
在第11
行第22
列。那麼,根據公式,可以得到c1
,2=a
1,1×
b2,1
+a1,
2×b2
,2c1
,2=
a1,1
×b2
,1+
a1,2
×b2
,2也就是說fi
−1=f
i−1×
b2,1
+fi−
2×b2
,2fi
−1=
fi−1
×b2
,1+
fi−2
×b2
,2那麼很明顯,我們可以得到b2,
1=1,
b2,2
=0b2
,1=
1,b2
,2=
0。這樣可以保證進行矩陣乘法之後c1,
2c1,
2是fi
那麼現在來看矩陣c
c中的fif
i。我們要保證的是c1
,1=a
1,1×
b1,1
+a1,
2×b2
,1c1
,1=
a1,1
×b1
,1+
a1,2
×b2
,1也就是說fi
=fi−
1×b1
,1+f
i−2×
b2,1
fi=
fi−1
×b1
,1+
fi−2
×b2
,1我們知道,fi=
fi−1
+fi−
2fi
=fi−
1+f
i−2
。所以可以得到b1,
那麼整個矩陣b
b都被我們求出來了。
得到了fif
i和fi
−1fi
−1後,我們再將它乘一次矩陣b
b,就可以得到fi+
1fi+
1和fi
fi,又可以得到fi+
2fi+
2和fi
+1..
.fi+
1..
.這樣就可以得到fnf
n了。但是!
你以為就結束了?
這樣的時間複雜度是o(n
m2)o
(nm2
),其中n
n表示求斐波那契數列的第n
n項,m
m表示矩陣的長寬。還不如遞推。而且遞推可以得到11到n
n的所有斐波那契數,而矩陣乘法只能求第nn項。
其實還有個地方可以優化。
我們求fnf
n的時候其實是將原矩陣a
a乘了n−1
n−1次矩陣b
b的。也就是說目標
矩陣=a
×bn−
1目標矩
陣=a×
bn−1
看到n−1n
−1次方想到了什麼?
可以用快速冪!
我們用快速冪的思想求出bn−
1bn−
1,然後再乘上乙個矩陣a
a即可。
怎麼用快速冪?
其實是乙個道理。只不過把矩陣a
a乘矩陣b
b換成矩陣b
b乘矩陣b
b就可以了。
那麼最終的時間複雜度為o(m
3log
n)o(
m3lo
gn)。還是很優秀的。**
**下面進入正題。
可以發現矩陣
然後就是套模板了。。。
#include
#include
#define mod 1000000007
#define ll long long
using
namespace std;
const ll b[4]
[4]=
,,,}
;int t,n;
ll f[4]
,a[4][
4];void
mul(ll f[4]
,ll a[4]
[4])
void
mulself
(ll a[4]
[4])
void
ask(
int x)
}int
main()
memcpy
(a,b,
sizeof
(b))
; f[1]
=f[2
]=f[3]
=1;ask
(n-3);
printf
("%lld\n"
,f[3])
;}return0;
}
洛谷P1939 模板 矩陣加速(數列)
a 1 a 2 a 3 1 a x a x 3 a x 1 x 3 求a數列的第n項對1000000007 10 9 7 取餘的值。輸入格式 第一行乙個整數t,表示詢問個數。以下t行,每行乙個正整數n。輸出格式 每行輸出乙個非負整數表示答案。輸入樣例 1 368 10 輸出樣例 1 4 919 對於...
洛谷P1939 模板 矩陣加速(數列)
a 1 a 2 a 3 1 a x a x 3 a x 1 x 3 求a數列的第n項對1000000007 10 9 7 取餘的值。第一行乙個整數t,表示詢問個數。以下t行,每行乙個正整數n。每行輸出乙個非負整數表示答案。36 81049 19對於30 的資料 n 100 對於60 的資料 n 2 ...
洛谷P1939 模板 矩陣加速(數列)
傳送門 a 1 a 2 a 3 1 a n a a quad n 3 有 t 組詢問。對每組詢問,給定 n 求 a n mod 1000000007 t leq 100,n leq 2 times 10 9 首先假定你會矩陣快速冪 不會的看 這裡 那麼,我們可以構造列向量 c begina a a ...