According to a research, VIM users tend to have shorter fingers, compared with Emacs users.
  Hence they prefer problems short, too. Here is a short one:
  Given n (1 <= n <= 10 18), You should solve for
g(g(g(n))) mod 10 9 + 7

where
g(n) = 3g(n - 1) + g(n - 2)( g(1) = 1, g(0) = 0)

Input
  There are several test cases. For each test case there is an integer n in a single line.
  Please process until EOF (End Of File).

Output
  For each test case, please print a single line with a integer, the corresponding answer to this case.
Sample Input

    0
    1
    2

Sample Output

    0
    1

ps:类似于2333矩阵,只是需要求出循环节,这个东西我不会2333, 网上找的找循环节的代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long mo1=1000000007;
long long mo2=222222224;
long long mo3=183120;
long long s1[3][3],s2[3][3],s3[3][3];
long long f(long long n,long long mo)
{
   
    int i,j,k;
    s1[0][0]=s2[0][0]=3;
    s1[0][1]=s2[0][1]=1;
    s1[1][0]=s2[1][0]=1;
    s1[1][1]=s2[1][1]=0;//对s[1], s[2]数组进行初始化
    n-=2;
    while (n)
    {
   
        {
   //如果n&1是1,s1=s1*s2;
            if (n&1)
            {
   
                memset(s3,0,sizeof(s3));
                for (k=0; k<2; k++)
                {
   
                    for (i=0; i<2; i++)
                    {
   
                        if (!s1[i][k])
                            continue;
                        for (j=0; j<2; j++)
                            s3[i][j]=(s3[i][j]+s1[i][k]*s2[k][j])%mo;
                    }
                }
                for (i=0; i<2; i++)
                    for (j=0; j<2; j++)
                        s2[i][j]=s3[i][j];//将s3的值赋给s2
            }
        }
        {
   //无论n&1是0还是1,s1=s1*s1;
            memset(s3,0,sizeof(s3));
            for (k=0; k<2; k++)
            {
   
                for (i=0; i<2; i++)
                {
   
                    if (!s1[i][k]) continue;
                    for (j=0; j<2; j++)
                        s3[i][j]=(s3[i][j]+s1[i][k]*s1[k][j])%mo;
                }
            }
            for (i=0; i<2; i++)
                for (j=0; j<2; j++)
                    s1[i][j]=s3[i][j];
        }
        n>>=1;
    }
    return s2[0][0];
}
int main()
{
   
    long long n;
    long long ans;
    while (~scanf("%lld",&n))
    {
   
        if (n==0)
        {
   
            printf("0\n");
            continue;
        }
        if (n==1)
        {
   
            printf("1\n");
            continue;
        }
        ans=f(n,mo3);
// printf("%d\n", ans);
        if (ans>=2) //一定要有,不然ans<2时函数就会死循环。
            ans=f(ans,mo2);
        if (ans>=2)
            ans=f(ans,mo1);
        printf("%lld\n",ans);
    }
}
//#include<cstdio>//**找循环节**
//long long mo1=1000000007;
//int main()
//{
   
// long long i=1,a=1,b=0,c;
// for(i=1, a=1, b=0;;)
// {
   
// while (i)
// {
   
// c=(3*a+b)%mo1;
// b=a;
// a=c;
// if (a==1&&b==0)
// {
   
// printf("%lld\n",i);
// break;
// }
// i++;
// }
// mo1=i;
// }
//}

其实关于矩阵快速幂,和快速幂是相差不多的,但是我就是搞不懂该怎么构建矩阵,曾经想强行理解一波,但是奈何理想很丰满,现实很骨感。