看到没有矩阵乘法的题解 一开始我是因为被推荐矩阵乘法才来写这一题的
楼下大佬们的数学公式很强 学到了
矩阵乘法是用矩阵优化达到递推logN解法的一种算法(大佬们无视)
可以用矩阵做的题推荐一道 https://nanti.jisuanke.com/t/16442
递推式是 设a()表示已经越狱的 b()表示没有越狱的
则 a(i)=a(i-1)m+b(i-1);表示已经越狱的最后一个人是什么都可以 没越狱的只能和倒数第二个一样
b(i)=(a(i-1)+b(i-1))m-a(i)=(m-1)*b(i-1);有m^n种可能 相减即可
b(1)=m;
下面贴代码
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;//不打long long 会WA
const ll MOD=100003;
ll i,j,n,m;
struct node{
ll s[2][2];
node(){
for(int i=0;i<=1;i++)
for(int j=0;j<=1;j++)
s[i][j]=0;
}//矩阵初始为0;
node operator * (const node& b){
node all;
for(int i=0;i<=1;i++)
for(int j=0;j<=1;j++)
for(int k=0;k<=1;k++){
all.s[i][j]+=s[i][k]*b.s[k][j];//矩阵乘法 不知道戳百科 (行的每个元素*列的每个元素)
all.s[i][j]%=MOD;//不能忘了取模
}
return all;//return矩阵
}
}a,b,ans;
node qpow(node t,ll k){
node w;w.s[0][0]=0;w.s[0][1]=m;//快速幂
for(ll i=k;i;i>>=1,t=t*t)
if(i&1)w=w*t;return w;
}
int main(){
scanf("%lld%lld",&m,&n);
a.s[0][0]=m;a.s[0][1]=0;//
a.s[1][0]=1;a.s[1][1]=m-1;//矩阵的初始化
ans=qpow(a,n-1);
printf("%lld",ans.s[0][0]);//输出
}