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.
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
题意:有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)种。
接下来是构造矩阵: