在\(2\times n\)的方格中用\(n-1\)塊\(2\times 1\)的方磚和\(2\)塊\(1\times 1\)的方磚填充,且兩塊\(1\times 1\)的方塊不能有相鄰的邊,求合法方案數。
啊,一道計數問題。反正我開始是這樣想的。
如果沒有那兩塊很礙事的磚,這不就是斐波拉契遞推嗎?,,,\(f[i]=f[i-1]+f[i-2]\),遞推走起。
好,現在來看那兩塊礙事的磚。
首先,我們會發現,這兩塊特別的磚會把整個方格分成三個部分,我們假設左右兩部分剛好是完整的(即是個矩形),那麼中間的塊就有性質了。
仔細推一推就會發現,當這兩個特殊的塊間隔奇數個塊時,這兩個塊必定在相異的兩行,並且中間只有一種方案構成。
同樣的,當這兩個特殊的塊間隔偶數個塊時,這兩個塊必定在相同的一行,並且中間也只有一種方案構成。
又因為不能有相鄰的邊,於是計算公式就出來了。
\[ans = 2 * \sum_^\sum_^f[j]*f[i-j]
\]細細理解下。
用這個大概只能得\(20pt\),我們想想怎麼優化?看到\(n<=2e+9\)的資料範圍,當然要往矩陣快速冪上面想咯。
矩陣的推法各有不同吧,我們來一步一步來拆這個式子。
設\(g(i)=\sum_^f(j)*f(i-j)\)。
所以\(\begin
\begin
g(i)&=\sum_^f(j)*f(i-j) \\
&=\sum_^f(j)*f(i-j)+f(i-1)*f(1)+f(i)*f(0)\\
&=\sum_^f(j)*[f(i-1-j)+f(i-2-j)]+f(i-1)+f(i)\\
&=g(i-2)+g(i-1)+f(i)
\end
\end\)
又設\(sum(i)=\sum_^g(j)\)
所以\(\begin
\begin
sum(i)&=\sum_^g(j) \\
&=\sum_^g(j)+g(i) \\
&=sum(i-1)+g(i-2)+g(i-1)+f(i)
\end
\end\)
所以易推得矩陣轉移方程:
\(\begin
f(i) \\
f(i-1) \\
g(i) \\
g(i-1) \\
sum(i) \\
\end
\right ]}\times
1 & 1 & 0 & 0 & 0\\
1 & 0 & 0 & 0 & 0 \\
1 & 1 & 1 & 1 & 0 \\
0 & 0 & 1 & 0 & 0 \\
1 & 1 & 1 & 1 & 1 \\
\end
\right ]}=
f(i+1)\\
f(i)\\
g(i+1)\\
g(i)\\
sum(i+1)
\end
\right ]}
\end\)
敲公式比敲字累多了。。。
於是\(o(125logn)\)可過。
哦,這個推法有點玄學,需要處理下邊界情況,具體情況見**。
#include#include#include#include#include#include#include#define ll long long
using namespace std;
const int max = 100000 + 5;
const int mod = 1e9 + 7;
inline int read() while (ch < '0'||ch>'9');
do while (ch >= '0' && ch <= '9');
return f*x;
}struct sakura a;
int t, n;
inline sakura mul(sakura a, sakura b)
} }return c;
}inline sakura mi(sakura a, int c)
return b;
}int main()
if (n == 3)
a.mar[0][0] = 1, a.mar[0][1] = 1, a.mar[0][2] = 0, a.mar[0][3] = 0, a.mar[0][4] = 0;
a.mar[1][0] = 1, a.mar[1][1] = 0, a.mar[1][2] = 0, a.mar[1][3] = 0, a.mar[1][4] = 0;
a.mar[2][0] = 1, a.mar[2][1] = 1, a.mar[2][2] = 1, a.mar[2][3] = 1, a.mar[2][4] = 0;
a.mar[3][0] = 0, a.mar[3][1] = 0, a.mar[3][2] = 1, a.mar[3][3] = 0, a.mar[3][4] = 0;
a.mar[4][0] = 1, a.mar[4][1] = 1, a.mar[4][2] = 1, a.mar[4][3] = 1, a.mar[4][4] = 1;
sakura ans = mi(a, n - 4);
ans.mar[4][0] <<= 1;
ans.mar[4][0] %= mod;
printf("%d\n", ans.mar[4][0]);
} return 0;
}
GXOI GZOI2019 逼死強迫症
傳送門 to luogu 將道路看成乙個很高很瘦的傢伙 乙個 n 2 n times 2 n 2 的瘦高個 考慮最後一行 或者說,第一行 是什麼情況。用 f n f n f n 表示答案。不好搞定的是第三種情況。下面都只討論第三種情況。如圖。不妨設第一行的 1 1 1 times 1 1 1 磚塊在...
GXOI GZOI2019 舊詞 解題報告
對於一棵 n 個節點的樹,給出 m 次詢問和常數 k 每次給出 r,x 求 sum limits r depth lca i,x k n,m le 5 times 10 4 1 le r,x le n k le 10 9 如果有做過 lnoi2014 lca,就很容易想出解法。可以通過樹上差分,點 ...
題解 GXOI GZOI2019 旅行者
調這個題調了兩個月,被自己蠢哭 給乙個有向圖,一組關鍵點,求關鍵點之間的最短的距離 這個題目有兩種做法,分別是 nlogn 和 nlog 2n 的 首先說 nlogn 的官方做法,我們考慮多源迪傑斯特拉 正圖上從 k 個關鍵點出發跑 dijkstra 記某個點離最近的關鍵點距離為 dis 0 i 反...