HDU 2604 Queuing 解题报告(讨论分析+矩阵快速幂)

Queuing

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4638    Accepted Submission(s): 2045


 

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 2Lnumbers 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

//----//

这个题目开始想了好久,没有找到方法,最后就看了看解题报告的图(就是下面那个图)就会了,主要是没有往这方面想,感觉一直在空想

对于长度为n的队列q(n),做以下讨论。

(转载而来)

图中 ,".....m"表示以字符'm'结尾的queue,其它类似。E_q表示E_queue。

可得:f(n)=f(n-1)+f(n-3)+f(n-4);

然后构建矩阵就行,其他的照抄模板就行了

下面贴上代码:

/* ************
当看不懂代码时
动手敲敲会好得多
************ */
#include<iostream>
#include<cmath>
#include <cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
int mod;
struct mat
{
    ll m[4][4];
    mat()
    {
        memset(m,0,sizeof(m));
    }
};
mat mul(mat &A,mat &B)
{
    mat C;
    for(int i=0;i<4;i++)
     {
         for(int j=0;j<4;j++)
            for(int k=0;k<4;k++)
                C.m[i][j]=(C.m[i][j]+A.m[i][k]*B.m[k][j])%mod;
     }
    return C;
}
mat pow(mat A,int n)
{
    mat B;
    for(int i=0;i<4;i++) B.m[i][i]=1;
    while(n)
    {
        if(n&1) B=mul(B,A);
        A=mul(A,A);
        n >>=1;
    }
    return B;
}

int main()
{
    ///f(n)=f(n-1)+f(n-3)+f(n-4)
    mat A;

    int L;
    A.m[0][0]=A.m[0][2]=A.m[0][3]=1;
    A.m[1][0]=1;
    A.m[2][1]=1;
    A.m[3][2]=1;

    while(scanf("%d%d",&L,&mod)!=EOF)
    {
        if(L>=4)
        {


        mat B=pow(A,L-4);



        printf("%lld\n",(B.m[0][0]*9+B.m[0][1]*6+B.m[0][2]*4+B.m[0][3]*2)%mod);
        }
        else if(L==3)
        {
            printf("%d\n",6%mod);
        }
        else if(L==2)
            printf("%d\n",4%mod);
        else printf("%d\n",2%mod);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42373330/article/details/81458911