[矩阵快速幂专题]

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): 8168    Accepted Submission(s): 3581

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
题意:求一个只含字符f和字符m的长度为L的字符串的种类数%m,要求其子串中不含有fff和fmf。
题解:设f(n)为长度为n的满足条件的字符串的个数,那么考虑第n个字符,第n个字符为m的话满足条件的个数为f(n-1),第n个字符为f的话,则最后几个字符应该为Xmmf或者Xmmff,其中X表示可以为m或者f,则个数也就是f(n-3)和f(n-4),所以f(n)=f(n-1)+f(n-3)+f(n-4),矩阵快速幂即可
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define debug(x) cout<<"["<<#x<<"]"<<"  "<<x<<endl;
 5 ll w[4][4],e[4][4];
 6 const int N=4;
 7 ll tmp[N][N],mod;
 8 void multi(ll a[][N],ll b[][N],int n)
 9 {
10     memset(tmp,0,sizeof tmp);
11     for(int i=0;i<n;i++)
12         for(int j=0;j<n;j++)
13         for(int k=0;k<n;k++)
14         {tmp[i][j]+=a[i][k]%mod*b[k][j]%mod;tmp[i][j]%=mod;}
15     for(int i=0;i<n;i++)
16         for(int j=0;j<n;j++)
17         a[i][j]=tmp[i][j];
18 }
19 ll res[N][N];
20 void Pow(ll a[][N],int n)
21 {
22     memset(res,0,sizeof res);//n是幂,N是矩阵大小
23     for(int i=0;i<N;i++) res[i][i]=1;
24     while(n)
25     {
26         if(n&1)
27             multi(res,a,N);//res=res*a;复制直接在multi里面实现了;
28         multi(a,a,N);//a=a*a
29         n>>=1;
30     }
31 }
32 void init(){
33     w[0][0]=1;
34     w[0][1]=0;
35     w[0][2]=1;
36     w[0][3]=1;
37 
38     w[1][0]=1;
39     w[1][1]=0;
40     w[1][2]=0;
41     w[1][3]=0;
42 
43     w[2][0]=0;
44     w[2][1]=1;
45     w[2][2]=0;
46     w[2][3]=0;
47 
48     w[3][0]=0;
49     w[3][1]=0;
50     w[3][2]=1;
51     w[3][3]=0;
52 }
53 int main()
54 {
55     int l;
56     e[0][0]=9;
57     e[1][0]=6;
58     e[2][0]=4;
59     e[3][0]=2;
60     while(scanf("%d%lld",&l,&mod)==2){
61         init();
62         if(l<4){
63             printf("%lld\n",e[l-1][0]%mod);
64         }
65         else{
66             Pow(w,l-4);
67             multi(res,e,4);
68             printf("%lld\n",res[0][0]);
69         }
70     }
71     return 0;
72 }
View Code

 

posted @ 2019-05-12 19:53  MekakuCityActor  阅读(230)  评论(0编辑  收藏  举报