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;
}
本文探讨了排队和优先队列数据结构在日常生活中的应用,通过定义女性和男性符号来构建队列,并计算特定长度下偶数队列的数量。采用矩阵快速幂加速算法解决计算复杂度问题。

被折叠的 条评论
为什么被折叠?



