source: 2017 multi-university training contest - team 2
題意:
給定 $ n $ , $ m $ , 求 $ f_ $
題解:
首先對基礎遞推式$$f_=f_+2\times f_$$加乙個sigma,有
$$\sum_^ f_ = \sum_^ f_ + 2\sum_^f_$$
即$$f_ = f_ +2 f_$$
歸納下去可得
$$f_ = f_ + 2f_$$
所以基礎遞推式對任意行標$i$都成立。先來遞推列,設矩陣
$$a_=\begin
f_ &f_&f_&f_
\end,b=\begin
0 &2&0&2\\
1& 1& 1 &1 \\
0& 0 & 1 & 0\\
0 & 0 &0 & 1
\end$$
則$$a_b=\begin
f_ &f_&f_+f_&f_+f_\\
\end$$
$$a_b^=\begin
f_ &f_&\sum_^f_&\sum_^f_\\
\end$$
$$=\begin
f_ &f_&f_&f_
\end$$
利用b矩陣遞推出了下一行的前兩個元素,為了使用快速冪遞推行,我們再構造乙個矩陣把$a_b^$調整到$a_$的形式。令
$$c=\begin
0&0&0&0\\
0& 0& 0 &0 \\
1& 0 & 1 & 0\\
0 & 1 &0 & 1
\end$$
則有$$a_b^c=\begin
f_ &f_&f_&f_\\
\end=a_$$
那麼就有
$$a_=a_(b^c)^$$
求出$a_$即得到答案。
然而這個題用4x4的矩陣會被卡常數....(官方題解是分奇偶2x2矩陣遞推)
喪心病狂的常數優化一下之後也能過,我加了讀入優化又把矩陣的struct拆成陣列之後700ms卡過去了....
#pragma comment(linker, "/stack:102400000,102400000")
#include #include #include #include #include #include #include #include #include #define ll long long
using namespace std;
const int mod = (int)(1e9)+7, maxn = 5, maxn = 5;
#define ll long long
const ll up = (ll)10000000*mod;
void get(int &x)
void get(ll &x)
void put(ll x)
int c[maxn][maxn];
void mul(int a[maxn][maxn], int b[maxn][maxn], int _c[maxn][maxn])
c[i][j] = tmp%mod;
tmp = 0;
} }for(int i = 1; i <= 4; i++) for(int j = 1; j <= 4; j++) _c[i][j] = c[i][j];
}int tmp[maxn][maxn], a[maxn][maxn];
void pow(int _a[maxn][maxn], ll x, int _b[maxn][maxn])
int a[maxn][maxn], b[maxn][maxn], c[maxn][maxn], b[maxn][maxn];
int main()
}
HDU2276 矩陣遞推
1.題目鏈結。題目大意,有n個燈,它們圍城乙個圈,每個燈有兩種狀態,0代表燈沒有開,1代表燈開著。現在做這樣的調整,每一秒,我們檢查這個燈的左邊 就是逆時針相鄰的那個點 如果左邊的點是1,那麼把該點的燈開啟,否則不做變化。問t秒之後所有燈的狀態。2.這是乙個矩陣的遞推,我們這樣考慮,a i j 代表...
HDU 5015 233 Matrix 矩陣遞推
題意 給出乙個矩陣,第一行從左到右分別是233,2333,23333,2333333。給出第一列的元素。其他的元素是它上面和左面的元素的和。求右下角元素的值。思路 在比賽的時候,總是想從右下角的元素遞推回去,找到公式,直接計算。發現沒法高效的求和。這道題正確的解法是利用矩陣從第二列開始遞推,每次得到...
HDU2604 Queuing 遞推 矩陣快速冪
題目鏈結 題意 男為f,女為m,求在長度為l的佇列中不存在fmf,fff這樣子序列的序列的個數。思路 又是遞推題,假設長度為l的佇列中存在的序列個數為f l 那麼考慮最後乙個放的字母,假設最後乙個放m,那麼前l 1個可以隨意排列,即個數為f l 1 如果最後乙個放f,那麼考慮後兩個字母,可能出現的情...