Problem: Forcing the obsessive-compulsive disorder (matrix fast power)

topic

Portal

Thinking

We set \ (ans_i \) to \ (2 * i \) matrix answers

So \ (ans_i \) how transfer it?

First thing is easy to understand

If the box is not special new entrants in the matrix

Then \ (ans_i = ans_ {i- 1} + ans_ {i-2} + x \)

Because for \ (2 * (i-1 ) and a 2 * (i-2) \ ) two matrices, if a particular block is not new incoming matrix,

It constitutes only one case

If a special box in the new entrants in the matrix it?

For two matrices marked red are mandatory,

And all matrices under special box must be on end, that is, only one program

After, on the special box is a classic model: \ (2 * number of programs with the n-matrix matrix 1 * 2 filled \)

To get the final transfer equation

\ (Ans_n ans_ = {n-1} + ans_ {n-2} + \ sum_ {i = 0} ^ {n-3} f_i \)

Where \ (f_i \) is the number of columns Feibolaqi

Wherein \ (f_0 = 1, f_1 = 1 \)

Code

#include<iostream>
#include<cstring>
using namespace std;
const long long mod=1e9+7;
struct node
{
    int n,m;
    long long a[10][10];
    node()
    {
        n=0;
        m=0;
        memset(a,0,sizeof(a));      
    }
    friend node operator * (const node &a,const node &b)
    {
        node t;
        t.n=a.n;
        t.m=b.m;
        for(int i=1;i<=a.n;i++)
            for(int j=1;j<=b.m;j++)
                for(int k=1;k<=a.m;k++)
                    t.a[i][j]=(t.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
        return t;
    }
}ori,acc;
long long T;
long long n;
node qkpow(node a,int b)
{
    if(b==1)
        return a;
    node t=qkpow(a,b/2);
    t=t*t;
    if(b%2==1)
        t=t*a;
    return t;
}
void c_in()
{
    cin>>n;
    if(n<=2)
    {
        cout<<"0\n";
        return;
    }
    if(n==3)
    {
        cout<<"2\n";
        return ;
    }
    ori.n=7;//f3 f2 s3 s2 s1 ans3 ans2
    //f为斐波拉契数列,s为前缀和,ans为答案
    ori.m=1;
    ori.a[1][1]=3;
    ori.a[2][1]=2;
    ori.a[3][1]=7;
    ori.a[4][1]=4;
    ori.a[5][1]=2;
    ori.a[6][1]=2;
    ori.a[7][1]=0;
    acc.n=7;
    acc.m=7;
    acc.a[1][1]=acc.a[1][2]=acc.a[2][1]=acc.a[3][1]=acc.a[3][2]=acc.a[3][3]=acc.a[4][3]=acc.a[5][4]=acc.a[6][6]=acc.a[6][7]=acc.a[7][6]=1;
    acc.a[6][5]=2;
    ori=qkpow(acc,n-3)*ori;
    cout<<ori.a[6][1]<<'\n';
}
int main()
{
    cin>>T;
    for(int i=1;i<=T;i++)
        c_in();
    return 0;
}

Guess you like

Origin www.cnblogs.com/loney-s/p/12051544.html