题目
答案
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull Pow(ull n)
{
ull a[2][2]={{1,1},{1,0}},tmp[2][2]={{1,0},{0,1}},tmp1,tmp2,tmp3,tmp4;
while(n)
{
if(n&1)
{
tmp1=tmp[0][0]*a[0][0]+tmp[0][1]*a[1][0];
tmp2=tmp[0][0]*a[0][1]+tmp[0][1]*a[1][1];
tmp3=tmp[1][0]*a[0][0]+tmp[1][1]*a[1][0];
tmp4=tmp[1][0]*a[0][1]+tmp[1][1]*a[1][1];
tmp[0][0]=tmp1%998244353,tmp[0][1]=tmp2%998244353,tmp[1][0]=tmp3%998244353,tmp[1][1]=tmp4%998244353;
}
tmp1=a[0][0]*a[0][0]+a[0][1]*a[1][0];
tmp2=a[0][0]*a[0][1]+a[0][1]*a[1][1];
tmp3=a[1][0]*a[0][0]+a[1][1]*a[1][0];
tmp4=a[1][0]*a[0][1]+a[1][1]*a[1][1];
a[0][0]=tmp1%998244353,a[0][1]=tmp2%998244353,a[1][0]=tmp3%998244353,a[1][1]=tmp4%998244353;
n>>=1;
}
return tmp[0][0]%998244353;
}
int main()
{
ull n;
cin>>n;
cout<<Pow(n-1);
}
注意
- 要先将每次更新后的矩阵值保存在tmp1到tmp4中,再在最后赋值(如果按顺序依次赋值,那么前面的值的改变会影响后面的运算,进而导致结果错误)
- 本题将记得取模,并将所有变量设置为`unsigned long long
总结
这道题采用了矩阵快速幂,详细方法可到下方链接中查找
https://zhuanlan.zhihu.com/p/54378423
同时,我采用的快速幂和原方法不同,我的方法类似于我的这篇文章——还在用pow函数做幂运算相关的算法题?快速幂表示不服!