vijos1049 矩阵乘法
题意
给你一个物品变换的顺序表,然后让你求变换了次之后物品的位置(n<=100, m<=10, k<=1e9)
分析
矩阵的妙用啊(0/1矩阵与原矩阵相乘即是变化结果),将每一行变化转化为一个0/1矩阵,所以m个变化可以转为为m个矩阵相乘,但矩阵乘法不符合交换律,符合结合律,所以必须将矩阵转置,分为k/m快速幂、k%m暴力模拟即可
#include <iostream>
#include<cstdlib>
#include<cstdio>
#include<map>
#include<vector>
#include<cstring>
#include<algorithm>
#define FOR(i,x,y) for(i=x;i<=y;++i)
#define maxn 1005
using namespace std;
int n,m,k;
struct matrix{
int mtx[105][105];
}mx[13];
matrix mul(matrix a, matrix b){
matrix ret;
memset(ret.mtx, 0, sizeof(ret.mtx));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
ret.mtx[i][j]+=a.mtx[i][k]*b.mtx[k][j];
}
}
}
return ret;
}
matrix qpow(matrix a, int n)
{
if(!n) return a;
matrix ret=a;
n--;
while(n)
{
if(n&1) ret=mul(ret, a);
a=mul(a,a);
n>>=1;
}
return ret;
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
int x;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
scanf("%d", &x);
mx[i].mtx[x][j]=1;
}
}
matrix ans=mx[1];
for(int i=2;i<=m;i++){
ans=mul(ans,mx[i]);
}
ans=qpow(ans,k/m);
k%=m;
for(int i=1;i<=k;i++){
ans=mul(ans,mx[i]);
}
matrix st;
for(int i=1;i<=n;i++){
st.mtx[1][i]=i;
}
st=mul(st, ans);
for(int i=1;i<=n;i++){
printf("%d ", st.mtx[1][i]);
}
printf("\n");
return 0;
}
要么优秀要么生锈