HDU—2604 Queuing

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. 

 

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的字符串,每一位可以填'f'或'm',如果某個字符串中任意相鄰的三個字符組成了"fmf"或"fff"就是所謂O隊列,不存在O隊列的字符串被稱爲E隊列,現在問長度爲L的E隊列有多少種,答案取模M

首先肯定考慮dp,顯然狀態是可以遞推的

設dp[n]表示長度爲n的E序列的方案數,那麼考慮什麼狀態可以轉移到dp[n]

第n位可以放的字符分別爲'f'和'm'

1.若放'm',那麼對前面n-1的序列沒有任何限制,則dp[n-1]可以全部轉移過來,則 +dp[n-1]

2.若放'f',那麼對前面的序列就有要求了,那麼再考慮往前一位到達[n-1],

   可以發現不管f[n-1]填'f'還是'm'都不能確定,因爲都有可能組成O隊列

   所以再往前考慮一位到達[n-2]

    若[n-1]填'm',那麼[n-2]只能填'm',那麼在這個情況下所有dp[n-3]都是滿足條件的狀態,則 +dp[n-3]

    若[n-1]填‘f’,那麼[n-2]只能填'm',在這個情況下並不是所有dp[n-3]都是滿足的狀態因爲[n-3]不能填'f',也就是[n-3]只能填'm',      那麼在這個情況下,所有dp[n-4]都是滿足條件的狀態,則 +dp[n-4]

以上

那麼就解決了遞推的問題

dp[n] = dp[n-1] + dp[n-3] + dp[n-4]

那麼因爲每次取模數都不一樣,所以不能預處理...雖然時間上可以預處理也就是30*1000000,但是要記錄的話就會MLE了...

所以考慮矩陣快速冪,這裏借用網上的矩陣圖

pic

【代碼】

#include <bits/stdc++.h>
using namespace std;
int n,MOD;
int a[6] = {1,2,4,6,9,15};
struct XX{
    int v[4][4];
    void init(){
    	memset(v,0,sizeof(v));
	    v[1][0] = v[0][0] = v[0][2] = 
		v[2][1] = v[3][2] = v[0][3] = 1;
	}
	void clear(){
		memset(v,0,sizeof(v));
	    for(int i = 0; i < 4; i ++)
	    	v[i][i] = 1;
	}
}x,s;

XX Mul(XX a,XX b){
    XX c;
    for(int i = 0; i < 4; i ++)
    for(int j = 0; j < 4; j ++){
        c.v[i][j] = 0;
        for(int k = 0; k < 4; k ++)
        	c.v[i][j] =(c.v[i][j] + (a.v[i][k] * b.v[k][j])%MOD ) % MOD;
    }
    return c;
}
void Matrix(int n)
{
    while(n){
        if(n & 1) x = Mul(x,s);
        n >>= 1;
        s = Mul(s,s);
    }
    int ans = 0;
    for(int i = 0; i < 4; i ++)
    	ans += (x.v[0][i] * a[4 - i])%MOD;
    printf("%d\n",ans%MOD);
}
int main()
{
    while(~scanf("%d%d",&n,&MOD))
    {
        if(n <= 4){
            printf("%d\n",a[n]%MOD);
            continue;
        }
        
        s.init();
        x.clear();
	    
        Matrix(n - 4);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章