zoukankan      html  css  js  c++  java
  • 【BZOJ4417】[Shoi2013]超级跳马 矩阵乘法

    【BZOJ4417】[Shoi2013]超级跳马

    Description

    现有一个n行m列的棋盘,一只马欲从棋盘的左上角跳到右下角。每一步它向右跳奇数列,且跳到本行或相邻行。跳越期间,马不能离开棋盘。例如,当n = 3, m = 10时,下图是一种可行的跳法。
     
    试求跳法种数mod 30011。

    Input

    仅有一行,包含两个正整数n, m,表示棋盘的规模。

    Output

    仅有一行,包含一个整数,即跳法种数mod 30011。

    Sample Input

    3 5

    Sample Output

    10

    HINT

    对于100%的数据,1 ≤ n ≤ 50,2 ≤ m ≤ 10^9

    题解:一开始搞了个200*200的矩阵,后来又搞了一个150*150的矩阵,最后发现100*100好像也行。。。不过不管了。

    用f[i][j]表示走到第i列,第j行的方案数,那么我们对于所有i为奇数的f维护前缀和s1,再对所有i为偶数的f维护前缀和s0,就可以转移了。

    不过。。。如果用分块矩阵乘法的话,我们要将f,s0,s1三个矩阵拼起来,一会从s0转移到f,一会从s1转移到f,怎么办呢?维护两个转移矩阵就好了嘛!我们设x表示从s0或s1到i的转移矩阵,具体地转移是这样的:

    令 $A=egin{pmatrix}\ & I &\ X & X & Iend{pmatrix}$,$B=egin{pmatrix}\ X & I & X\ & & Iend{pmatrix}$,我们的ans矩阵就是ans*A*B*A*B...,我们令C=A*B,所以就变成了$ans*C^{m>>1}$,最后可能再乘一个A。

    P.S:同学提供了一个更巧妙的做法,令方程为f[i][j]=f[i-2][j]+f[i-1][j-1]+f[i-1][j]+f[i-1][j+1],然后维护个100*100的矩阵就行了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int P=30011;
    int n,m;
    struct M
    {
    	int a[160][160];
    	int * operator [] (int b) {return a[b];}
    	M () {memset(a,0,sizeof(a));}
    	M operator * (M b)
    	{
    		M c;	int i,j,k;
    		for(i=1;i<=3*n;i++)	for(j=1;j<=3*n;j++)	for(k=1;k<=3*n;k++)	c[i][j]=(c[i][j]+a[i][k]*b[k][j])%P;
    		return c;
    	}
    };
    M ans,A,B,C;
    void pm(int y)
    {
    	while(y)
    	{
    		if(y&1)	ans=ans*C;
    		C=C*C,y>>=1;
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&m),m--;
    	int i;
    	ans[1][1]=ans[1][2*n+1]=1;
    	for(i=1;i<=n;i++)
    	{
    		if(i>1)	A[2*n+i][i-1]=A[2*n+i][n+i-1]=B[n+i][i-1]=B[n+i][2*n+i-1]=1;
    		A[2*n+i][i]=A[2*n+i][n+i]=A[2*n+i][2*n+i]=A[n+i][n+i]=B[n+i][i]=B[n+i][n+i]=B[n+i][2*n+i]=B[2*n+i][2*n+i]=1;
    		if(i<n)	A[2*n+i][i+1]=A[2*n+i][n+i+1]=B[n+i][i+1]=B[n+i][2*n+i+1]=1;
    	}
    	C=A*B;
    	pm(m>>1);
    	if(m&1)	ans=ans*A;
    	printf("%d",ans[1][n]);
    	return 0;
    }
  • 相关阅读:
    asp.net连接数据库,在web.config中配置数据库连接
    在处理向该请求提供服务所需的配置文件时出错。请检查下面的特定错误详细信息并适当地修改配置文件如何解决
    centos7查看CPU的利用率
    阿里云云盘在线扩容
    微信和支付宝付款码条码规则(官方)
    微信和支付宝付款码条码规则
    IPFS与般若文海
    Moira果老星宗七政四余排盘软件下载
    Odoo 电子公章/印章模块
    playtoearn
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7561492.html
Copyright © 2011-2022 走看看