CS Academy Partial Ladder Graph
リンク : https://csacademy.com/contest/archive/task/partial_ladder_graph/statement/
問題概要
N2頂点とN+2(N-1)辺のグラフが与えられる。1<=i<=N-1 の頂点iはi+1同士を結んでいる。N<=i<=2N-1も同様である。また、1<=i<=N-1の頂点iと頂点i+(N-1)は結ばれている。このとき、辺を削除しても連結である、辺の集合の通り数を求めよ。
解説
Nが1から2に変わったときに、辺1-2、辺2-4、辺3-4の3辺のみしか変わらないため、一つ前の遷移が使えるのではという考察と、N<=から繰り返し二乗法か行列累乗が浮かぶ。そこでdp[i][0]をi番目までで、これからの遷移によっては連結になりうる通り数(現在は連結でない)とし、dp[i][1]をi番目までで、現在連結である通り数とする。そうすると、公式解説の図のように考えると、
dp[i+1][0]=dp[i][0]+dp[i][1]×2
dp[i+1][1]=dp[i][0]+dp[i][1]×4
となる。普通に計算してしまうとTLEである。この形なら行列累乗ができるため、O(log N)でこの問題が解ける。
LL n; int main() { cin >> n; n--; matrix<LL>mat(2), A(2,1); A.mat[0][0] = 1; A.mat[1][0] = 1; mat.mat[0][0] = 1; mat.mat[0][1] = 2; mat.mat[1][0] = 1; mat.mat[1][1] = 4; matrix<LL>ANS(mat.Pow(n)*A); cout << ANS.mat[1][0] << endl; return 0; }