题解 P5303 【[GXOI/GZOI2019]逼死强迫症】
可以先去考虑没有
设没有
用同样的方法考虑有
当最后一个位置需要铺设为
设
然后就可以递推来求解了,但是发现
设矩阵
然后每次询问矩阵快速幂一下就好了。
#include<bits/stdc++.h>
#define p 1000000007
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
ll T,n;
struct matrix
{
ll a[6][6];
matrix()
{
memset(a,0,sizeof(a));
}
}m,ans;
matrix operator *(const matrix &a,const matrix &b)
{
matrix c;
for(int i=0;i<5;++i)
for(int j=0;j<5;++j)
for(int k=0;k<5;++k)
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%p+p)%p;
return c;
}
matrix qp(matrix x,ll y)
{
matrix e;
for(int i=0;i<5;++i) e.a[i][i]=1;
while(y)
{
if(y&1) e=e*x;
x=x*x,y>>=1;
}
return e;
}
ll m1[6][6]=
{
{2,0,1,1,1}
};
ll m2[6][6]=
{
{1,1,0,0,0},
{1,0,0,0,0},
{2,0,1,1,1},
{0,0,1,0,0},
{2,0,0,0,1}
};
int main()
{
read(T);
memcpy(ans.a,m1,sizeof(ans.a));
memcpy(m.a,m2,sizeof(m.a));
while(T--)
{
read(n);
if(n<3) puts("0");
else printf("%lld\n",(ans*qp(m,n-3)).a[0][0]);
}
return 0;
}