【51Nod算法马拉松18 B】非010串

来源:互联网 发布:淘宝销售宣传标语 编辑:程序博客网 时间:2024/05/17 07:21

Description

如果一个01字符串满足不存在010这样的子串,那么称它为非010串。
求长度为n的非010串的个数。(对1e9+7取模)

Solution

最喜欢签到题了。
f[i][j]表示到第i个点,末尾的状态是j(01,00,10,11四个状态),转移很显然。
然后在转成矩阵乘法就好了。

Code

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int mo=1000000007;typedef long long ll;ll i,j,k,l,t,n,m;ll ans;typedef long long ll;struct ju{    ll a[16][16];    ju friend operator *(ju a,ju b){        ju c;memset(c.a,0,sizeof(c.a));        int i,j,k;        fo(i,0,15){            fo(j,0,15){                fo(k,0,15){                    c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mo)%mo;                }            }        }        return c;    }}a,b;ju qsm(ju x,ll y){    ju z;    memset(z.a,0,sizeof(z.a));fo(i,0,15)z.a[i][i]=1;    while(y){        if(y&1)z=z*x;        x=x*x;        y/=2;    }    return z;}int main(){    scanf("%lld",&n);    if(n==1){        printf("2\n");        return 0;    }    a.a[0][0]=a.a[0][1]=1;    a.a[1][3]=1;    a.a[2][0]=a.a[2][1]=1;    a.a[3][2]=a.a[3][3]=1;    b.a[0][0]=b.a[0][1]=b.a[0][2]=b.a[0][3]=1;    b=b*qsm(a,n-2);    fo(i,0,3)(ans+=b.a[0][i])%=mo;    printf("%lld\n",ans);}
2 0
原创粉丝点击