hlg神秘植物--矩阵快速幂

神秘植物
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submit: 42(20 users) Total Accepted: 20(16 users) Rating:  Special Judge: No
Description

Leyni有一种神秘的植物,形状是一种“向上”三角形植物,每过一年,每个“向上”三角形植物会变成三个“向上”三角形植物和一个“向下”三角形植物,每个“向下”三角形植物会变成三个“向下”三角形植物和一个“向上”三角形植物。如下图:


 

Leyni想知道经过n年有多少个“向上”三角形植物。

Input

输入包含多组测试数据。

对于每组测试数据:

1行,包含一个整数n (0 ≤ n ≤ 1018)

处理到文件结束

Output

对于每组测试数据:

1行,输出Leyni拥有多少个“向上”三角形植物。(MOD 1000000007)

Sample Input

1

2

Sample Output

3

10

Author
齐达拉图@HRBUST

大意:

思路:

初看这个题以为是找规律,

结果还真找到了规律,不过由于数量级太大 所以用矩阵快速幂来解决

规律: 每一个图形的向上和向下的个数都是通过上一个图形的向上和向下的个数得来的  

而一个向上的可以得到3个向上的和1个向下的

一个向下的可以得到1个向上的和3个向下的

所以   :第i个图形  向上的三角形的个数  =  第i-1个图形 向上的三角形的个数*3   +   第i-1个图形 向下的三角形的个数*1

代码:

  1 #include <iostream>
  2 #include <string.h>
  3 #include <stdio.h>
  4 using namespace std;
  5 
  6 const int mod=1000000007;
  7 
  8 long long int xx[2][2]={
  9     {3,1},
 10     {1,3}
 11 };
 12 
 13 long long int start[1][2]={
 14     3,1
 15 };
 16 // 2 2 * 2 2
 17 void mul1(long long int a[2][2],long long int b[2][2],long long int c[2][2])
 18 {
 19     for(int i=0;i<2;i++)
 20     {
 21         for(int j=0;j<2;j++)
 22         {
 23             c[i][j]=0;
 24             for(int x=0;x<2;x++)
 25             {
 26                 c[i][j]+=((a[i][x]%mod)*(b[x][j]%mod)%mod);
 27                 c[i][j]%=mod;
 28             }
 29         }
 30     }
 31 }
 32 
 33 //1 2 * 2 2
 34 void mul2(long long int a[1][2],long long int b[2][2],long long int c[1][2])
 35 {
 36     for(int i=0;i<1;i++)
 37     {
 38         for(int j=0;j<2;j++)
 39         {
 40             c[i][j]=0;
 41             for(int x=0;x<2;x++)
 42             {
 43                 c[i][j]+=((a[i][x]%mod)*(b[x][j]%mod)%mod);
 44                 c[i][j]%=mod;
 45             }
 46         }
 47     }
 48 }
 49 
 50 //diguui
 51 
 52 void cal(long long int x,long long int a[2][2])
 53 {
 54     long long int b[2][2];
 55     if(x==1)
 56     {
 57         for(int i=0;i<2;i++)
 58         {
 59             for(int j=0;j<2;j++)
 60             {
 61                 a[i][j]=xx[i][j];
 62                 a[i][j]%=mod;
 63             }
 64         }
 65         return ;
 66     }
 67     if(x%2==0)
 68     {
 69         cal(x/2,b);
 70         mul1(b,b,a);
 71     }
 72     else if(x%2==1)
 73     {
 74         cal(x-1,b);
 75         mul1(b,xx,a);
 76     }
 77 }
 78 
 79 int main()
 80 {
 81     long long int n;
 82     while(scanf("%lld",&n)!=EOF)
 83     {
 84         if(n==0)
 85         {
 86             printf("1
");
 87             continue;
 88         }
 89         if(n==1)
 90         {
 91             printf("3
");
 92             continue;
 93         }
 94         long long int mid[2][2];
 95         long long int end[1][2];
 96         cal(n-1,mid);
 97         mul2(start,mid,end);
 98         printf("%lld
",end[0][0]);
 99     }
100     return 0;
101 }
View Code

  

原文地址:https://www.cnblogs.com/zhanzhao/p/3652846.html