链接:https://ac.nowcoder.com/acm/contest/1087/C
一行一个整数表示答案
解释:
我没做出来的原因是没推出来这个式子,矩阵的题目就是前后有联系,这样的式子我没推出来。
按照斐波那契的性质推了很久也没有发现什么公式,看题解也是直接说“很容易就得到”....不过我们可以通过直接对所求式子打表的方式来观察规律。这个打表是很容易的,只是这个规律如果对斐波那契没什么感觉的话很难观察得到(第n项等于二倍的n-1项+n-2项-二倍的n-3项-n-4项)。
推出了这个式子,我们就可以构造矩阵了,由于这个式子是4向量表示,我们要构造的矩阵也一定是四阶的,也就是说我们要构造的这个矩阵乘以n-1项就等于第n项
然后我们就可以使用矩阵快速幂递推求出,然后我们只需要寻找从0开始的次数就可以了
注意这道题的一个坑是初始矩阵的方向
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
#define mod 998244353
ll n;
void mul(ll f[4],ll a[4][4])
{
ll c[4];
memset(c,0,sizeof(c));
for(ll j=0; j<4; j++)
for(ll k=0; k<4; k++)
c[j]=(c[j]+(f[k]*a[k][j])%mod)%mod;
memcpy(f,c,sizeof(c));
}
void mulself(ll a[4][4])
{
ll c[4][4];
memset(c,0,sizeof(c));
for(ll i=0; i<4; i++)
for(ll j=0; j<4; j++)
for(ll k=0; k<4; k++)
c[i][j]=(c[i][j]+(a[i][k]*a[k][j])%mod)%mod;
memcpy(a,c,sizeof(c));
}
int main()
{
scanf("%lld",&n);
ll f[4]= {0,0,1,2};
ll a[4][4]= {
{0,0,0,-1},{1,0,0,-2},{0,1,0,1},{0,0,1,2}};
n=n;
for(; n; n>>=1)
{
if(n&1)
mul(f,a);
mulself(a);
}
printf("%lld\n",(f[0]+mod)%mod);
return 0;
}
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
#define mod 998244353
ll n;
void mul(ll f[4],ll a[4][4])
{
ll c[4];
memset(c,0,sizeof(c));
for(ll j=0; j<4; j++)
for(ll k=0; k<4; k++)
c[j]=(c[j]+(f[k]*a[k][j])%mod)%mod;
memcpy(f,c,sizeof(c));
}
void mulself(ll a[4][4])
{
ll c[4][4];
memset(c,0,sizeof(c));
for(ll i=0; i<4; i++)
for(ll j=0; j<4; j++)
for(ll k=0; k<4; k++)
c[i][j]=(c[i][j]+(a[i][k]*a[k][j])%mod)%mod;
memcpy(a,c,sizeof(c));
}
int main()
{
scanf("%lld",&n);
if(n<=3)
{
if(n==1) cout<<0<>=1)
{
if(n&1)
mul(f,a);
mulself(a);
}
printf("%lld\n",(f[0]+mod)%mod);
}