zoukankan      html  css  js  c++  java
  • 51nod 算法马拉松18 B 非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

        读完题,这样的题目肯定是能找到规律所在的,要不然数据太大根本无法算。假设现在给的长度是n,答案为f(n),那么假设最后一位是0,前面有010的可能就有f(n-1)种,同样假设最后一位是1,前面有010的可能就也有f(n-1),而这样排除的话还存在着一个问题,就是最后为0的时候可能会出现前面是01而构成010,这样就加重复了。所以假设前一位为1,再减去f(n-2),当然还可能前面是11而构成110而不是010,所以还要把多减的再加回来,即再加上一个f(n-3),这样一来就可以推出一个公式,f(n)=2*f(n-1)-f(n-2)+f(n-3)。看到这个公式,数据有那么大,所以我们用矩阵快速幂来进行处理就可以快速得出结果了。

        下面是AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const long long mod=1000000007;
    
    struct matrix
    {
        long long a[3][3];
    };
    
    matrix cal(matrix A,matrix B)
    {
         int i,j,k;
         matrix C;
         for(i=0;i<3;i++)
         {
              for(j=0;j<3;j++)
              {
                   C.a[i][j]=0;
                   for(k=0;k<3;k++)
                   {
                        C.a[i][j]=(C.a[i][j]+(A.a[i][k]*B.a[k][j])%mod+mod)%mod;
                   }
              }
         }
         return C;
    }
    
    int out(matrix A,matrix B)
    {
         cout<<"s:"<<endl;
         cout<<A.a[0][0]<<" "<<A.a[0][1]<<" "<<A.a[0][2]<<endl;
         cout<<A.a[1][0]<<" "<<A.a[1][1]<<" "<<A.a[1][2]<<endl;
         cout<<A.a[2][0]<<" "<<A.a[2][1]<<" "<<A.a[2][2]<<endl;
         cout<<"base:"<<endl;
         cout<<B.a[0][0]<<" "<<B.a[0][1]<<" "<<B.a[0][2]<<endl;
         cout<<B.a[1][0]<<" "<<B.a[1][1]<<" "<<B.a[1][2]<<endl;
         cout<<B.a[2][0]<<" "<<B.a[2][1]<<" "<<B.a[2][2]<<endl;
         return 0;
    }
    
    matrix pow_mod(long long x)
    {
         matrix s,base;
         base.a[0][0]=2;
         base.a[1][0]=-1;
         base.a[2][0]=1;
         base.a[0][1]=1;
         base.a[1][1]=base.a[2][1]=0;
         base.a[1][2]=1;
         base.a[0][2]=base.a[2][2]=0;
         s.a[0][0]=7;
         s.a[0][1]=4;
         s.a[0][2]=2;
         s.a[1][0]=s.a[1][1]=s.a[1][2]=0;
         s.a[2][0]=s.a[2][1]=s.a[2][2]=0;
         out(s,base);
         while(x)
         {
              if(x&1)
                   s=cal(s,base);
              base=cal(base,base);
              out(s,base);
              x>>=1;
         }
         return s;
    }
    
    int main()
    {
         long long n;
         long long ans;
         while(scanf("%lld",&n)!=EOF)
         {
              if(n==0)
                   cout<<0<<endl;
              else if(n==1)
                   cout<<2<<endl;
              else if(n==2)
                   cout<<4<<endl;
              else if(n==3)
                   cout<<7<<endl;
              else
              {
                   matrix t=pow_mod(n-3);
                   ans=t.a[0][0]%mod;
                   cout<<ans<<endl;
                   /*cout<<t.a[0][1]%mod<<endl;
                   cout<<t.a[1][0]%mod<<endl;
                   cout<<t.a[1][1]%mod<<endl;*/
              }
         }
         return 0;
    }
  • 相关阅读:
    CSS大杂烩(1)
    菜鸟快飞之JavaScript函数
    mysqldump主要参数分析
    PXC原理分析
    MHA原理分析
    android数据存储之外部存储(External Storage)
    JsonWriter使用
    基于asp.net mvc的近乎产品开发培训课程(第二讲)
    基于asp.net mvc的近乎产品开发培训课程(第一讲)
    MVC的注意事项及开发技巧
  • 原文地址:https://www.cnblogs.com/lmhbk/p/5919666.html
Copyright © 2011-2022 走看看