矩阵——vijos1049送给圣诞夜的礼品
https://vijos.org/p/1049
其实这道题《十个利用矩阵乘法解决的经典题目》里面有;
这题其实思想,只要你学过矩阵,可以直接出来的;
但是我还是卡住了;
因为矩阵不满足交换律;
矩阵乘法不满足交换律,这个和矩阵的长宽没有关系,它就是不满足交换律;
我还以为只要是方形的就可以交换;
但是我们怎么知道谁前谁后呢,这个和矩阵构造有关;
如果我们的矩阵是以行为单位构造出来,显然它要以行为单位得据算,所以要放到前;
反之后;
那么有没有矩阵满足交换律?
有
两个相同的矩阵
比如快速幂里面的乘法原始矩阵
1000
0100
0010
0001
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#define Ll long long
using namespace std;
struct jv{
int n,m;
int a[101][101];
jv(){n=m=0;memset(a,0,sizeof a);}
}a[11],ans,v;
int n,m,k,x,y;
jv cheng(jv a,jv b){
jv ans; ans.n=a.n; ans.m=b.m;
for(int i=1;i<=a.n;i++)
for(int k=1;k<=a.m;k++)if(a.a[i][k])
for(int j=1;j<=b.m;j++)
ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j]);
return ans;
}
jv ksm(int y){
jv ans=v,c=v;
y-=1;
while(y){
if(y&1)ans=cheng(ans,c);
y>>=1;
c=cheng(c,c);
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++){
a[i].n=a[i].m=n;
for(int j=1;j<=n;j++){
scanf("%d",&x);
a[i].a[j][x]=1;
}
}
v=a[1];
for(int i=2;i<=m;i++)v=cheng(a[i],v);
ans.n=n; ans.m=1;
for(int i=1;i<=n;i++)ans.a[i][1]=i;
if(k>=m)ans=cheng(ksm(k/m),ans);
for(int i=1;i<=k%m;i++)ans=cheng(a[i],ans);
for(int i=1;i<=n;i++)cout<<ans.a[i][1]<<' ';
}