非010串

非010串

基准时间限制:1 秒 空间限制:131072 KB 分值: 80
如果一个01字符串满足不存在010这样的子串,那么称它为非010串。
求长度为n的非010串的个数。(对1e9+7取模)
Input
一个数n,表示长度。(n<1e15)
Output
长度为n的非010串的个数。(对1e9+7取模)
Input示例
3
Output示例
7

解释:
000
001
011
100
101
110
111

思路:矩阵快速幂;

末尾的状态可以看成是01,10,11,00四种状态,那么考虑新加入的是0,和1,进行状态转移,最后矩阵快速幂求解。
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<queue>
  6 #include<stack>
  7 #include<math.h>
  8 using namespace std;
  9 typedef long long LL;
 10 typedef struct node
 11 {
 12         LL m[4][4];
 13         node()
 14         {
 15                 memset(m,0,sizeof(m));
 16         }
 17 } maxtr;
 18 const int mod = 1e9+7;
 19 maxtr E();
 20 void Init(maxtr *p);
 21 maxtr quick_m(maxtr ans,LL m);
 22 int main(void)
 23 {
 24         LL n;
 25         scanf("%lld",&n);
 26         if(n == 1)
 27                 printf("2
");
 28         else if(n == 2)
 29                 printf("4
");
 30         else
 31         {
 32                 n-=2;
 33                 maxtr ak;
 34                 Init(&ak);
 35                 maxtr ask = quick_m(ak,n);
 36                 LL sum = 0;
 37                 int i ,j;
 38                 for(i = 0; i < 4; i++)
 39                 {
 40                         for(j = 0; j < 4; j++)
 41                         {      //printf("%lld
",ak.m[i][j]);
 42                                 sum = sum+ask.m[i][j];
 43                                 sum%=mod;
 44                         }
 45                 }
 46                 printf("%lld
",sum);
 47         }
 48         return 0;
 49 }
 50 maxtr E()
 51 {
 52         maxtr e;
 53         int i,j;
 54         for(i = 0; i < 4; i++)
 55         {
 56                 for(j = 0; j < 4; j++)
 57                 {
 58                         if(i == j)
 59                                 e.m[i][j] = 1;
 60                         else e.m[i][j] = 0;
 61                 }
 62         }return e;
 63 }
 64 void Init(maxtr *p)
 65 {
 66         memset(p->m,0,sizeof(p->m));
 67         p->m[0][0] = 1;
 68         p->m[0][2] = 1;
 69         p->m[1][0] = 1;
 70         p->m[1][2] = 1;
 71         p->m[2][3] = 1;
 72         p->m[3][1] = 1;
 73         p->m[3][3] = 1;
 74 }
 75 maxtr quick_m(maxtr ans,LL m)
 76 {
 77         maxtr C = E();
 78         while(m)
 79         {
 80                 if(m&1)
 81                 {
 82                         maxtr dp;
 83                         for(int i = 0; i < 4; i++)
 84                         {
 85                                 for(int j = 0; j < 4; j++)
 86                                 {
 87                                         for(int s = 0; s < 4; s++)
 88                                         {
 89                                                 dp.m[i][j] = dp.m[i][j] + ans.m[i][s]*C.m[s][j]%mod;
 90                                                 dp.m[i][j] %= mod;
 91                                         }
 92                                 }
 93                         }
 94                         C = dp;
 95                 }
 96                 maxtr ak;
 97                 for(int i = 0; i < 4; i++)
 98                 {
 99                         for(int j = 0; j < 4; j++)
100                         {
101                                 for(int s = 0; s < 4; s++)
102                                 {
103                                         ak.m[i][j] = ak.m[i][j] + ans.m[i][s]*ans.m[s][j]%mod;
104                                         ak.m[i][j]%=mod;
105                                 }
106                         }
107                 }
108                 ans = ak;
109                 m/=2;
110         }
111         return C;
112 }


油!油!you@
原文地址:https://www.cnblogs.com/zzuli2sjy/p/5908430.html