詳 析 GXOI GZOI2019 逼死強迫症

2022-04-08 06:27:13 字數 2746 閱讀 5210

在\(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 反...