• hdu6030 经典矩阵快速幂+递推关系


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6030

    题目要求给出一个长度为n的串,要求这个串中任意长度为素数的连续序列中r的数量多于或者等于b,我们不难得出只要长度为2或者3的序列都满足这个条件就能得出整个序列满足题目要求的条件,简单的证明如下:如果是长度为偶数的素数,那一定只有2,满足最小性条件,如果是大小为奇数的素数代表的连续区间,则这个奇数可以分解成若干个2和3,的短序列,由于序列条件的可加性。所以整个序列也是满足条件的。对于递推关系,可以考虑局部的转移规则,因为长度为2和3的区间需要考虑,所以我们每次递推的时候就考虑2->3长度的转移过程。用an表示末两位为rr的方案数,bn表示末位为rb的方案数,cn表示末位为br的方案数,所以总共的方案数有an+bn+cn,初值为a2=b2=c2=1,有关系 an=an-1+cn-1,bn=an-1,cn=bn-1.根据关系构造矩阵即可在O(logn)时间内求出an+bn+cn;

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define mp(a,b) make_pair((a),(b))
    17 #define P pair<int,int>
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x7ffffff
    20 inline int read(){
    21     int ans=0,w=1;
    22     char ch=getchar();
    23     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    24     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    25     return ans*w;
    26 }
    27 int t;
    28 ll n;
    29 const int maxn=3;
    30 const ll mod=1e9+7;
    31 struct mat{
    32     ll a[maxn][maxn];
    33     mat()
    34     {
    35         f(i,0,maxn-1)
    36             f(j,0,maxn-1)
    37                 a[i][j]=0;
    38     }
    39     mat operator * (const mat &x)const 
    40     {
    41         mat c;
    42         f(i,0,maxn-1)
    43             f(j,0,maxn-1)
    44                 f(k,0,maxn-1)
    45                 {
    46                     c.a[i][j]=(c.a[i][j]+a[i][k]*x.a[k][j])%mod;        
    47                  } 
    48                 return c;
    49     }
    50 };
    51 mat pow_mod(mat A,ll k)
    52 {
    53     mat ans;
    54     ans.a[0][0]=ans.a[1][1]=ans.a[2][2]=1;
    55     while(k)
    56     {
    57         if(k&1)ans=ans*A;
    58         A=A*A;
    59         k>>=1;
    60     }
    61     return ans;
    62 }
    63 int main()
    64 {
    65     //freopen("input.txt","r",stdin);
    66     //freopen("output.txt","w",stdout);
    67     std::ios::sync_with_stdio(false);
    68     t=read();
    69     mat A;
    70     A.a[0][0]=A.a[0][2]=A.a[1][0]=A.a[2][1]=1;
    71     while(t--)
    72     {
    73         scanf("%lld",&n);
    74         if(n==2)
    75         {
    76             pf("3
    ");
    77             continue;
    78         }
    79         ll ans=0;
    80         mat tmp=pow_mod(A,n-2);
    81         f(i,0,maxn-1)
    82             f(j,0,maxn-1)
    83             {
    84                 ans=(ans+tmp.a[i][j])%mod;
    85             }
    86             pf("%lld
    ",ans);
    87     }
    88 } 
  • 相关阅读:
    Android应用视觉效果设计技巧
    Android实现图片缩放与旋转
    schema 对象的简单介绍
    Index Scans 索引扫描
    Oracle Database Transaction Isolation Levels 事务隔离级别
    第一篇博客,纪念一下,终于开通啦!
    Linux 开机引导流程
    springBoot中tomcat默认端口修改
    面向服务架构之RPC原理与实例
    vs2008中xlslib与libxls库的编译及使用
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12726383.html
Copyright © 2020-2023  润新知