1. 程式人生 > >粉櫻花之戀(矩陣快速冪求斐波拉契數列)

粉櫻花之戀(矩陣快速冪求斐波拉契數列)

qn是個特別可愛的小哥哥,qy是個特別好的小姐姐,他們兩個是一對好朋友 [ cp (劃掉~) 又是一年嚶花爛漫時,小qn於是就邀請了qy去嚶花盛開的地方去玩。當qy和qn來到了田野裡時,qy驚奇的發現,嚶花花瓣以肉眼可見的速度從樹上長了出來。 仔細看看的話,花瓣實際上是以一定規律長出來的,而且,每次張成新的花瓣的時候,上一次的花瓣就會都落到地上,而且不會消失。 花瓣生長的規律是,當次數大於等於2時,第i次長出來的花瓣個數和上一次張出來的花瓣個數的差是斐波那契數列的第i-1項。初始的時候地上沒有花瓣,樹上的花瓣個數為1,第一次生長的花瓣個數為1。初始的那個花瓣就落到了地上

現在,小qn想知道,經過k次生長之後,樹上和地上的總花瓣個數是多少?

ps:斐波那契數列:

    f[1]=f[2]=1;f[i]=f[i-1]+f[i-2] (i>=2且i   N+) 

輸入描述:

一行一個數k

輸出描述:

一行一個數m,表示第k次生長過後,樹上和地上的總花瓣數是多少。由於答案會很大,請你將答案mod 998244353後輸出

示例1

輸入

4

輸出

12

說明

第一次:樹上1,地上1.第二次樹上2,地上1+1,第三次樹上3,地上1+1+2,第四次樹上5,地上1+1+2+3。總共12個

示例2

輸入

5

輸出

20

說明

第五次樹上8,地上1+1+2+3+5。總共20個

備註:

對於0%的資料,有k=樣例
對於20%的資料,有k<=1'000
對於60%的資料,有k<=1'000'000
對於80%的資料,有k<=1'000'000'000
對於100%的資料,有k<1'000'000'000'000'000'000

所以這個題就十分明朗了。雖然簡單,,但是一直不會構造初始矩陣,這次終於算是搞懂了。(線代喲~~~)

就這樣了......

該題程式碼如下:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#define mod 998244353 
struct node
{
    long long v[3][3];
    long long int m,l;
};
node get_mul(node a,node b)
{
    node c;
    c.m=a.m;c.l=b.l;
    for(long long int i=1;i<=c.m;i++)
      for(long long int j=1;j<=c.l;j++)
      {
          c.v[i][j]=0;
          for(long long int k=1;k<=a.l;k++)
              c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%mod;
      }
    return c;
}

int main()
{
        long long int n;
        scanf("%lld",&n);
        if(n==0) {printf("1\n");return 0;}//注意這個特判0
        node a,b,c;
        a.m=a.l=2,a.v[1][1]=1,a.v[1][2]=1,a.v[2][1]=1,a.v[2][2]=0;
        b.m=b.l=2,b.v[1][1]=1,b.v[1][2]=0,b.v[2][1]=0,b.v[2][2]=1;
        c.m=2,c.l=1,c.v[1][1]=1,c.v[2][1]=0;
        n+=2;
        while(n)
        {
            if(n&1) b=get_mul(a,b);
            a=get_mul(a,a);
            n>>=1;
        }
        b=get_mul(b,c);
        printf("%lld\n",b.v[1][1]-1);
    return 0;
}