首页 > 其他分享 >P3990 [SHOI2013]超级跳马

P3990 [SHOI2013]超级跳马

时间:2023-02-24 13:45:25浏览次数:40  
标签:奇数 int 矩阵 P3990 init && 跳马 SHOI2013

首先可以想到一个位置状态会从与自己相差不到一行,相差列为奇数的列转移过来,那么很明显对于每一行可以求奇数位置或是偶数位置的前缀和。

设 \(f_{i,j}\) 为跳到第 \(i\) 行第 \(j\) 列的方案数,\(g_{i,j}\) 代表第 \(i\) 行第 \(j\) 列的 \(\sum_{k\ne j(\bmod 1)}f_{i,k}\),即同行与自己相差奇数列的前缀和。

那么可以写出转移方程。

\(f_{i,j}=g_{i-1,j-1}+g_{i,j-1}+g_{i+1,j-1}\)

\(g_{i,j}=g_{i-2,j}+f_{i,j}\)

这样就可以矩阵加速了,初始矩阵从上到下分别为 \(f_{k,j}\),\(g_{k,j}\) 和 \(g_{k,j-1}(1\le k\le n)\)。

剩下的转移矩阵在对应位置上加 \(1\) 即可,对此操作如果有疑问可以多去复习下矩阵快速幂。

复杂度:\(O(27n^3\times \log(m))\)。

#include<iostream>
#include<cstdio>
using namespace std;
const int mod=30011;
const int N=105;
struct matrix
{
	int x,y,a[155][155];
	void init()
	{
		for(int i=1;i<=x;i++)for(int j=1;j<=y;j++)a[i][j]=0;
	}
};
matrix operator *(matrix fi,matrix se)
{
	matrix th;
	th.x=fi.x,th.y=se.y;
	th.init();
	for(int i=1;i<=fi.x;i++)
	{
		for(int j=1;j<=se.y;j++)
		{
			for(int k=1;k<=fi.y;k++)
			{
				th.a[i][j]+=fi.a[i][k]*se.a[k][j];
				th.a[i][j]%=mod;
			}
		}
	}
	return th;
}
matrix quick_pow(matrix x,int y)
{
	matrix num=x,sum;
	sum.x=sum.y=num.x;
	sum.init();
	for(int i=1;i<=sum.x;i++)sum.a[i][i]=1;
	while(y)
	{
		if(y&1)sum=sum*num;
		num=num*num;
		y>>=1;
	}
	return sum;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	matrix x,y;
	x.x=x.y=3*n;
	x.init();
	y.x=3*n,y.y=1;
	y.init();
	y.a[1][1]=y.a[1+n][1]=1;
	for(int i=1;i<=n;i++)
	{
		int x1=i+n-1,x2=i+n,x3=i+n+1;
		if(x1>n&&x1<=2*n)x.a[i+n][x1]=x.a[i][x1]=1;
		if(x2>n&&x2<=2*n)x.a[i+n][x2]=x.a[i][x2]=1;
		if(x3>n&&x3<=2*n)x.a[i+n][x3]=x.a[i][x3]=1;
	}
	for(int i=n+1;i<=2*n;i++)x.a[i][i+n]=1;
	for(int i=2*n+1;i<=3*n;i++)x.a[i][i-n]=1;
	x=quick_pow(x,m-1);
	y=x*y;
	printf("%d",y.a[n][1]);
	return 0;
}

标签:奇数,int,矩阵,P3990,init,&&,跳马,SHOI2013
From: https://www.cnblogs.com/gmtfff/p/p3990.html

相关文章

  • P3997 [SHOI2013]扇形面积并 题解
    理解题意后可以把题目看成一个覆盖线段的问题。对于点在\(-m\)上,看成在\(m\)上。对于\(l<r\),不用处理。对于\(l>r\),将问题看成\((l,m)\)和\((-m+1.r)\)两个区......
  • 跳马问题
    题目:洛谷P1644跳马问题题目背景在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧……题目描述中国象棋半张棋盘如图1所示。马自左下角(0,0)向右上角(m,n)跳。......
  • P1644 跳马问题 C++ 搜索回溯+dfs
    题目背景在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧……题目描述中国象棋半张棋盘如图1所示。马自左下角(0,0)向右上角(m,n)跳。规定只能往......