矩阵快速幂(queue递推)

http://acm.hdu.edu.cn/showproblem.php?pid=2604

Queuing

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


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 2L 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
 
Author
WhereIsHeroFrom
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  1588 2606 2276 2603 3117
 
题意:有2的L次方个组合队列,求出不包含子序列fmf和fff的个数;
思路:根据长度增长变化可发现,fn就是在f(n-1)已知序列后加上f或m变化而来。根据题意可推出
递推式:
fn     0 1 2 1 2    f(n-1)
ff      0 0 0 0 1    ff(子序列的数量)
mm    0 0 1 1 0    mm
fm      0 1 0 0 1    fm
mf      0 0 1 0 0    mf
 
#include<bits/stdc++.h>
using namespace std ;
#define int long long 
typedef long long ll ;
const int N = 100009  , maxn = 4;
int n , m ;
int mod ;
struct node{
	int a[maxn][maxn];//矩阵
	node(){memset(a , 0 , sizeof(a));}
	node operator * (const node &B)const{
		node C ;
		for(int i = 0 ; i < maxn ; i++){
			for(int j = 0 ; j < maxn ; j++){
				for(int k =  0 ; k < maxn ; k++){
					C.a[i][j] = (C.a[i][j] + (a[i][k] % mod * B.a[k][j] % mod) % mod) % mod;
				}
			}
		}
		return C;
	} 
};

node qpow(node A , int b){//A矩阵的b次方
	node C ;
	for(int i = 0 ; i < maxn ; i++){
		C.a[i][i] = 1 ;
	}
	while(b){
		if(b&1){
			C = C * A ; 
		}
		b >>= 1 ;
		A = A * A ;
	}
	return C;
}
int a[4][4] = {{0,0,0,1},{1,0,0,1},{0,1,1,0},{0,0,1,0}};

void solve(){
    if(n == 0){
        cout << 0 << endl;
        return ;
    }
    if(n == 1){
        cout << 2 << endl;
        return ;
    }
    node A , B , C;
    B.a[0][0] = B.a[1][0] = B.a[2][0] = B.a[3][0] = 1 ;
    for(int i = 0 ; i < maxn ; i ++){
        for(int j = 0 ; j < maxn ; j++){
            A.a[i][j] = a[i][j] ;
        }
    }
    C = qpow(A , n - 2) * B  ;
    int ans = 0 ;
    for(int i = 0 ; i < maxn ; i++){
        ans += C.a[i][0] ;
        ans %= mod ;
    }
    cout << ans << endl;
}

signed main(){
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\c++\in.txt", "r", stdin);
        //freopen("D:\c++\in.txt", "w", stdout);
    #endif
    //int t ;
    //scanf("%lld" , &t);
    //while(t--)
    while(cin >> n >> mod)
        solve();
}

 不过这道题还有别的递推式:

递推方程:f(n)=f(n-1)+f(n-3)+f(n-4)。

  如果第n位是f,它前面是f时(ff),再前一位必须是m(mff),再前一位还必须是m(mmff),所以有f(n-4)种;

         它前面是m时(mf),再前一位必须是m(mmf),再前就任意了,所以有f(n-3)种

  第n位是m,它前面可以是任意的,所以有f(n-1)种。

  接下来是构造矩阵:

原文地址:https://www.cnblogs.com/nonames/p/11360347.html