hdu2604Queuing(矩阵快速幂+递推)

题目链接https://vjudge.net/problem/HDU-2604

题目如下

Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time.


  Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2 L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue else it is a E-queue.
Your task is to calculate the number of E-queues mod M with length L by writing a program.

Input

Input a length L (0 <= L <= 10 6) and M.

Output

Output K mod M(1 <= M <= 30) where K is the number of E-queues with length L.

Sample Input

3 8
4 7
4 8

Sample Output

6
2
1

假设队长为L时E-queues的数目为F(L)

F(0)=0    F(1)=2   F(2)=4   F(3)=6  F(4)=9

当L较大时,假设第L是m那么只要L-1符合条件就好,有F(L-1)种情况

如果第L个是f ,由题意,考虑前面两个,总的情况有fff ,fmf, mff,mmf但是fff,fmf不和条件,只考虑

mmf,mff两种情况

对于mmf,只要前面L-3符合条件就好,有F(L-3)中情况

对于mff,第L-3个只能是m,那么只要前面L-4个符合条件就好,有F(L-4)种情况

综上推出F(L)=F(L-1)+F(L-3)+F(L-4)

那么

接下来就用矩阵快速幂处理(相关介绍见https://mp.csdn.net/postedit/82084564 )

代码如下

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
int eline[4]={2,4,6,9};
int mod,l;
struct matrix
{
	ll s[4][4];
}base;
matrix operator*(matrix a,matrix b)
{
	matrix c;
	memset(c.s,0,sizeof(c.s));
	for(int i=0;i<4;i++)
		for(int j=0;j<4;j++)
		for(int k=0;k<4;k++)
		c.s[i][j]+=(a.s[i][k]%mod)*(b.s[k][j]%mod)%mod;
	return c;
}
ll pow_mod()
{
	matrix a;
	memset(a.s,0,sizeof(a.s));
	memset(base.s,0,sizeof(base.s));
	for(int i=0;i<4;i++)
		a.s[i][i]=1;
	base.s[0][0]=1,base.s[0][1]=0,base.s[0][2]=1,base.s[0][3]=1;
	for(int i=0;i<3;i++)base.s[i+1][i]=1;
	int k=l-4;
	while(k)
	{
		if(k&1)a=a*base;
		base=base*base;
		k>>=1;
	}
	ll result=0;
	for(int i=0;i<4;i++)
		result+=a.s[0][i]*eline[4-i-1];
	return result%mod;
}
int main()
{
	while(scanf("%d%d",&l,&mod)!=EOF)
	{
		ll res;
		if(l==0)res=0;
		else if(l<=4)res=eline[l-1]%mod;
		else res=pow_mod();
		cout<<res<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41626975/article/details/82108316