[题解]P5550 |Chino的数列
人生第一道矩乘题,一遍过
分析
对于数据范围进行分析,\(n\) 很小而 \(k\) 很大,可以考虑到矩阵快速幂优化递推
考虑构造一个矩阵来存储 \(a\) 数组,
即:\(A=\left\|a_1,a_2,\cdots,a_n\right\|\)
操作1
我们把数组前移一位,利用矩阵乘法的原理,可以构造出 \(B_1\) 使
\(A*B_1=\left\|a_2,a_3,\cdots,a_n,a_1\right\|\)
如对于样例,\(B_1=\left\|\begin{array}{cc}0&0&0&1\\1&0&0&0\\0&1&0&0&\\0&0&1&0\end{array}\right\|\)
操作2
我们把数组交换两位,利用矩阵乘法的原理,可以构造出 \(B_2\) 使
\(A*B_2=\left\|a_1,a_2,\cdots,a_{s-1},a_m,a_{s+1},\cdots,a_{m-1},a_s,a_{m+1},\cdots,a_n\right\|\)
此时我们只需将单位矩阵中的两列交换即可
如对于样例,\(B_2=\left\|\begin{array}{cc}0&1&0&0\\1&0&0&0\\0&0&1&0&\\0&0&0&1\end{array}\right\|\)
结合
根据矩阵乘法那套理论手玩样例,将 \(B_1\) 和 \(B_2\) 相乘即可得到 \(B=B_1*B_2\)
根据矩阵乘法具有结合律,我可以用快速幂加速矩阵递推,则最终结果为 \(A*B^k\) 的第一行
代码
\(\mathcal{Code:}\)
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 100010
#define int long long
#define debug cout<<__LINE__<<" "<<__FUNCTION__<<"\n"
inline int read(){
int x=0,y=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')y=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*y;
}
void put(int x){
if(x<0) putchar('-'),x=-x;
if(x>=10) put(x/10);
putchar((x%10)+48);
}
int n,s,m,t;
struct Martix{
int c[110][110];
Martix(){memset(c,0,sizeof c);}
friend Martix operator * (const Martix &x,const Martix &y){
Martix res;
for(int i=1;i<=n;i++)//枚举矩阵1的行
for(int j=1;j<=n;j++)//枚举矩阵2的列
for(int k=1;k<=n;k++)//累加
res.c[i][j]+=x.c[i][k]*y.c[k][j];
return res;
}
}ans,a;
inline Martix ksm(Martix a,int b){
Martix res;
for(int i=1;i<=n;i++) res.c[i][i]=1;//记得赋单位矩阵
while(b){
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read();s=read();m=read();t=read();
for(int i=1;i<=n;i++) ans.c[1][i]=read();
for(int i=1;i<=n;i++){//B1
a.c[i%n+1][i]=1;
}
swap(a.c[s],a.c[m]);//交换两列
//我直接将两个矩阵合并了,两种写法等价
ans=ans*ksm(a,t);
for(int i=1;i<=n;i++) cout<<ans.c[1][i]<<" ";
// fclose(stdin);
// fclose(stdout);
return 0;
}