zoukankan      html  css  js  c++  java
  • 题解【LOJ #3086 [GXOI/GZOI2019]逼死强迫症】

    [ exttt{Description} ]

    ITX351 要铺一条 (2 imes n) 的路,为此他购买了 (n)(2 imes 1) 的方砖。可是其中一块砖在运送的过程中从中间裂开了,变成了两块 (1 imes 1) 的砖块!
    ITX351 由此产生了一个邪恶的想法:他想要在这条路上故意把两块 (1 imes 1) 的砖块分开铺,不让两块砖有相邻的边,其他砖块可以随意铺,直到整条路铺满。这样一定可以逼死自身强迫症 sea5!

    也许下面的剧情你已经猜到了 —— 他为此兴奋不已,以至于无法敲键盘。于是,他请你帮忙计算一下,有多少种方案可以让自己的阴谋得逞。

    多组询问。
    数据范围:(1 leq T leq 500)(1 leq n leq 10^9)

    [ exttt{Solution} ]

    考虑 dp。

    (f_n) 表示:根据题意,铺设一条 (2 imes n)合法道路的方案数。

    转移有两种:

    1. (n) 列不存在 (1 imes 1) 的方砖。

      1. 在第 (n) 列竖着放一个 (2 imes 1) 的方砖,得到一个规模为 (n - 1) 的子问题。
      2. 在第 (n - 1) 列和第 (n) 列横着放两个 (2 imes 1) 的方砖,得到一个规模为 (n - 2) 的子问题。
    2. (n) 列存在 (1 imes 1) 的方砖。

      此时,可以考虑另一块 (1 imes 1) 的方砖的位置。

      这一块 (1 imes 1) 的方砖只能放在第 (1) 列至第 (n - 2) 列中。
      注意到每一列,有且仅有一个位置可填,至于是 " 同行还是异行 " 与 " 列数差的奇偶性 " 有关。

      更进一步,假设说这个 (1 imes 1) 的方砖放在了第 (i) 列,则:

      • ((1))(i) 列至第 (n) 列里所有方砖的方法是唯一确定的。
      • ((2))(1) 列至第 (i - 1) 列里所有方砖可以随便摆放。

      那主要考虑 ((2)) 的情况。

      (g_n) 表示:只使用 (2 imes 1) 的方砖,铺设一条 (2 imes n)合法道路的方案数。显然有:

    [ g_0=1, g_1 = 1 \ g_n = g_{n - 1} + g_{n - 2} ]

    综上,有转移:

    [f_n = f_{n - 1} + f_{n - 2} + 2 ast sumlimits_{0 leq i leq n - 3} g_i ]

    至此,此题已经可以使用矩阵快速幂解决。


    但是这个转移看起来就很不爽。
    我们希望可以把他化简一下。

    注意到数列 ({ g_n }) 与斐波那契数列 ({ fib_n }) 恰好错位了一位。

    而斐波那契数列的前缀和有一个非常美妙的性质:

    [sumlimits_{i = 1} ^ n fib_i = fib_{n + 2} - 1 ]

    可以使用数学归纳法简单证明一下:

    (n = 1) 时,命题显然成立。

    假设当 (n = m) 时,命题成立。
    (n = m + 1) 时:

    [egin{aligned}fib_{m + 3} - 1 & = fib_{m + 1} + fib_{m + 2} - 1\& = fib_{m + 1} + sumlimits_{i = 1} ^ m fib_{i}\& = sumlimits_{i = 1}^{m + 1} fib_iend{aligned} ]

    故原命题成立,QED。

    于是就可以使用斐波那契数代替 (sumlimits_{0 leq i leq n - 3} g_i),得到转移:

    [f_n = f_{n - 1} + f_{n - 2} + 2 ast fib_{n} - 2 ]

    具体的,令设矩阵 (F(n) = egin{bmatrix} f_n & f_{n - 1} & fib_{n} & fib_{n - 1} & -2 end{bmatrix})
    则:

    [F(n) ast egin{bmatrix} 1 & 1 & 0 & 0 & 0 \ 1 & 0 & 0 & 0 & 0 \ 2 & 0 & 1 & 1 & 0 \ 2 & 0 & 1 & 0 & 0 \ 1 & 0 & 0 & 0 & 1 end{bmatrix} = F(n + 1) ]

    先把 (n = 1, 2) 的情况判掉。
    对于 (n geq 3) 的情况,最终的答案矩阵即为 (F(2) ast A^{n - 2}),其中 (A) 为上式中的转移矩阵。

    单组数据时间复杂度 (mathcal{O}(5^3 log n))

    [ exttt{Code} ]

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int mod = 1e9 + 7;
    
    int n;
    
    int f[6];
    int A[6][6];
    
    void mulstar(int f[6], int a[6], int b[6][6]) {
    	static int c[6]; memset(c, 0, sizeof(c));
    	for (int j = 1; j <= 5; j ++)
    		for (int k = 1; k <= 5; k ++)
    			c[j] = (c[j] + 1ll * a[k] * b[k][j]) % mod;
    	memcpy(f, c, sizeof(c));
    }
    
    void mul(int f[6][6], int a[6][6], int b[6][6]) {
    	static int c[6][6]; memset(c, 0, sizeof(c));
    	for (int i = 1; i <= 5; i ++)
    		for (int j = 1; j <= 5; j ++)
    			for (int k = 1; k <= 5; k ++)
    				c[i][j] = (c[i][j] + 1ll * a[i][k] * b[k][j]) % mod;
    	memcpy(f, c, sizeof(c));
    }
    
    void work() {
    	scanf("%d", &n);
    
    	if (n == 1 || n == 2) {
    		puts("0");
    		return;
    	}
    
    	// 初始矩阵 F(2) 
    	f[1] = 0, f[2] = 0, f[3] = 1, f[4] = 1, f[5] = mod - 2;
    
    	// 转移矩阵 A
    	A[1][1] = 1, A[1][2] = 1, A[1][3] = 0, A[1][4] = 0, A[1][5] = 0;
    	A[2][1] = 1, A[2][2] = 0, A[2][3] = 0, A[2][4] = 0, A[2][5] = 0;
    	A[3][1] = 2, A[3][2] = 0, A[3][3] = 1, A[3][4] = 1, A[3][5] = 0;
    	A[4][1] = 2, A[4][2] = 0, A[4][3] = 1, A[4][4] = 0, A[4][5] = 0;
    	A[5][1] = 1, A[5][2] = 0, A[5][3] = 0, A[5][4] = 0, A[5][5] = 1;
    
    	for (int b = n - 2; b; b >>= 1) {
    		if (b & 1) mulstar(f, f, A);
    		mul(A, A, A);
    	}
    
    	printf("%d
    ", f[1]);
    }
    
    int main() {
    	int T;
    	scanf("%d", &T);
    
    	while (T --)    work();
    
    	return 0;
    }
    

    [ exttt{Thanks} exttt{for} exttt{reading} ]

  • 相关阅读:
    DirectX9:基础篇 第六章 颜色
    DirectX9:应用篇 论OBJ模型文件格式
    MFC:绘图基础
    DirectX9:基础篇 纹理
    DirectX9:应用篇 论OBJ模型文件和.X模型文件互转
    MFC:控件位置调整
    数据结构:二叉树
    DirectX9:总结篇 数据类型结构
    C89:论结构体/枚举体/联合体的使用
    css布局汇总
  • 原文地址:https://www.cnblogs.com/cjtcalc/p/14191796.html
Copyright © 2011-2022 走看看