Queuing
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3274 Accepted Submission(s): 1487
Problem Description
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.
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
6
2
1
【思路分析】
设f(n)为长度为n时满足条件的值。
1、当最后一位为m时,由于fff和fmf的最后一位均为f,所以,此时前n - 1位没有限制,即f(n) = f(n - 1);
2、当最后一位为f时,有mmf、mff、fff、fmf这四种情况,其中后两种情况不满足条件。
(1)当后三位为mmf时,可知前n - 3位没有限制,即f(n) = f(n - 3);
(2)当后三位为mff时,后四位有mmff、fmff两种情况,可知第二种不满足条件,即f(n) = f(n - 4)。
综上可知f(n) = f(n - 1) + f(n - 3) + f(n - 4)。
由于n 在10^6之内,直接递推会导致超时,所以要采取矩阵快速幂加速:
代码如下:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 0;
const int SIZE = 4;
int l,mod;
struct Matrix
{
long long value[SIZE][SIZE];
Matrix()//构造方法
{
memset(value,0,sizeof(value));
}
void init(long long v)
{
for(int i = 0;i < SIZE;i++)
{
value[i][i] = v;
}
}
};
Matrix operator * (Matrix a,Matrix b)
{
Matrix c;
memset(c.value,0,sizeof(c.value));
for(int i = 0;i < SIZE;i++)
{
for(int j = 0;j < SIZE;j++)
{
for(int k = 0;k < SIZE;k++)
{
c.value[i][j] += (a.value[i][k] * b.value[k][j]) % mod;
c.value[i][j] %= mod;
}
}
}
return c;
}
Matrix operator ^ (Matrix a,long long k)
{
Matrix c;
c.init(1);//单位矩阵
while(k)
{
if(k & 1)
{
c = a * c;
}
a = a * a;
k = k >> 1;
}
return c;
}
int main()
{
Matrix queues,temp,res;
memset(queues.value,0,sizeof(queues.value));
memset(temp.value,0,sizeof(temp.value));
queues.value[0][0] = 9;//f(4)
queues.value[1][0] = 6;//f(3)
queues.value[2][0] = 4;//f(2)
queues.value[3][0] = 2;//f(1)
temp.value[0][0] = temp.value[0][2] = temp.value[0][3] = temp.value[1][0] = temp.value[2][1]
= temp.value[3][2] = 1;
while(scanf("%d %d",&l,&mod) != EOF)
{
if(l == 0)
{
printf("0\n");
}
else if(l <= 4)
{
printf("%lld\n",queues.value[4 - l][0] % mod);
}
else
{
res = temp ^ (l - 4);
res = res * queues;
printf("%lld\n",res.value[0][0] % mod);
}
}
return 0;
}