Luogu P5303 [GXOI / GZOI2019] Forcing OCD

How there are so many topics ah SB province

First easy to think of a right of enum \ (1 \ times 1 \) column of small squares where \ (i \) , and then the storm left column pieces small box where \ (j \) Where, then we found all \ (j \ in [1, i -1) \) of the columns there is only an option, and particularly about the difference between both the ordinate, FIG draw know

Then each pair \ (i, j \) contribution is how much, is very simple, apparently \ ([i, j] \ ) column has only one placement program between then be multiplied by the coefficient on both sides is \ (2 \ times (i-1 ) \) and \ (2 \ times (nj) \) size of the discharge method

We make \ (2 \ times i \) is placed as the program size \ (F_i \) , each considering the right place, either vertically from \ (f_ {i-1} \) transferred from either sideways two discharge from \ (f_ {i-2} \) transfer to, so this is a Fibonacci number

Then consider the idea in front of that violence, we pretreated the \ (f_i \) and \ (f_i \) prefix and \ (s_i \) to get 50pts (pay attention to the right of the upper and lower two methods equivalent to each other, so to \ (\ Times 2 \) )

50pts Violence Code

#include<cstdio>
#define RI register int
using namespace std;
const int N=1e5+5,mod=1e9+7;
int t,n,ans,fib[N],sum[N];
inline void init(void)
{
    sum[0]=fib[0]=fib[1]=1; for (RI i=sum[1]=2;i<N;++i)
    fib[i]=(fib[i-2]+fib[i-1])%mod,sum[i]=(sum[i-1]+fib[i])%mod;
}
int main()
{
    for (scanf("%d",&t),init();t;--t)
    {
        RI i; for (scanf("%d",&n),ans=0,i=3;i<=n;++i)
        (ans+=2LL*sum[i-3]*fib[n-i]%mod)%=mod; printf("%d\n",ans);
    }
    return 0;
}

Then we again similar to \ (f_i \) Derivation Derivation answer \ (F_i \) , to consider how the transfer came from the previous state

It is easy to use the same idea obtained, if the previous (i-1 \) \ columns not put \ (1 \ times 1 \) a small box, then \ (F_i \) from \ (F_ {i-1} \) and \ (F_ {i-2} \) is transferred by

If you put it, it is actually a transfer process above violence, because we are at this time in the first \ (i \) put the method column only, therefore the coefficient is \ (1 \)

Therefore, there is comprehensive look \ (F_i = F_ {} + I-2 I-F_ {}. 1 +2 \ Times-S_ {I}. 3 \) , followed by the Fibonacci column prefix and the nature of the \ (s_i = f_ {i + 2} -1 \ ) can be introduced \ (F_i = F_ {i- 2} + F_ {i-1} +2 \ times f_ {i-1} -2 \)

Fast power to maintain direct transfer matrix \ (5 \) values (a is a constant term), the complexity of the \ (O (T \ times 5 ^ 3 \ times \ log n) \)

100pts moment multiply CODE

#include<cstdio>
#include<cstring>
#define RI register int
#define CI const int&
using namespace std;
const int N=5,mod=1e9+7;
struct Matrix
{
    int n,m; long long mat[N][N];
    inline Matrix(CI N=0,CI M=0) { n=N; m=M; memset(mat,0,sizeof(mat)); }
    inline long long* operator [] (CI x) { return mat[x]; }
    friend inline Matrix operator * (Matrix A,Matrix B)
    {
        Matrix C(A.n,B.m); for (RI i=0;i<C.n;++i)
        for (RI j=0;j<C.m;++j) for (RI k=0;k<A.m;++k)
        (C[i][j]+=A[i][k]*B[k][j])%=mod; return C;
    }
    friend inline Matrix operator ^ (Matrix A,long long p)
    {
        Matrix T(A.n,A.m); for (RI i=0;i<A.n;++i) T[i][i]=1;
        for (;p;p>>=1LL,A=A*A) if (p&1) T=T*A; return T;
    }
}; int t,n;
int main()
{
    for (scanf("%d",&t);t;--t)
    {
        scanf("%d",&n); if (n<=2) { puts("0"); continue; }
        Matrix S(5,1),D(5,5); S[2][0]=S[3][0]=1; S[4][0]=2;
        D[0][0]=D[0][1]=D[1][0]=D[2][2]=D[2][3]=D[3][2]=D[4][4]=1;
        D[0][2]=2; D[0][4]=mod-1; S=(D^(n-1))*S; printf("%d\n",S[0][0]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/cjjsb/p/10961051.html