Meaning of the questions:
\ (M_i \) a \ (m * m \) matrix, known
\ [\ begin {aligned} & M_0 = A \\ & M_i = (\ prod_ {j = c_i} ^ {i + 1} M_j) B \ end {aligned} \]
Q \ (M_n \) matrix, comprising an input \ (n-, m, A, B, c_1 and \ cdots C_N (c_1 and \ Leq c_2 \ cdots \ C_N Leq) \) .
Ideas:
Since \ (c_1 \ Leq c_2 \ cdots \ Leq c_n \) , so we only need to implement a queue to meet the team from head \ (POP \) , from the tail \ (the Push \) , and can find the product in the queue. It can be achieved in two stacks.
Stack \ (suf \) saved is the product suffix, \ (pre \) saved is the product of a prefix, then the \ (push \) when it is placed \ (pre \) to maintain and store the product prefix go into matrix \ (pop \) directly when \ (suf \) front of the suffix pop can. If \ (suf \) is empty, so the \ (pre \) in the suffix into violence becomes \ (suf \) inside. Each matrix can know the stack into a maximum of two, the complexity of the \ (O (nm ^ 2) \) .
Code:
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<bitset>
#include<string>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6 + 5;
const int M = 50 + 5;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
struct Mat{
int s[5][5];
void init(){memset(s, 0, sizeof(s));}
};
int n, m, mod;
int ksc(ll a, ll b, ll p){
ll t = a * b - (ll)((long double)a * b / p + 0.5) * p;
t = (t < 0)? t + p : t;
return (int)t;
}
inline Mat mul(Mat a, Mat b){
Mat c;
c.init();
for(int i = 0; i < m; i++){
for(int j = 0; j < m; j++){
for(int k = 0; k < m; k++){
c.s[i][j] = (c.s[i][j] + ksc(a.s[i][k], b.s[k][j], mod)) % mod;
}
}
}
return c;
}
Mat pre[maxn], suf[maxn], a[maxn];
int cnt1, cnt2, c[maxn];
void ins(Mat x){
if(cnt1 == 0) pre[++cnt1] = x;
else{
pre[++cnt1] = x;
pre[cnt1] = mul(pre[cnt1 - 1], x);
}
a[cnt1] = x;
}
void del(){
if(cnt2 == 0){
for(int i = cnt1; i >= 1; i--){
if(cnt2 == 0) suf[++cnt2] = a[i];
else suf[++cnt2] = a[i], suf[cnt2] = mul(suf[cnt2], suf[cnt2 - 1]);
}
cnt1 = 0;
}
cnt2--;
}
int main(){
while(~scanf("%d%d%d", &n, &m, &mod)){
cnt1 = cnt2 = 0;
Mat A, B, ret;
for(int i = 0; i < m; i++){
for(int j = 0; j < m; j++){
scanf("%d", &A.s[i][j]);
}
}
for(int i = 0; i < m; i++){
for(int j = 0; j < m; j++){
scanf("%d", &B.s[i][j]);
}
}
for(int i = 1; i <= n; i++) scanf("%d", &c[i]);
int L = 0;
ins(A);
for(int i = 1; i <= n; i++){
while(L < c[i]) del(), L++;
if(cnt1 && cnt2) ret = mul(suf[cnt2], pre[cnt1]);
else if(cnt1) ret = pre[cnt1];
else ret = suf[cnt2];
ret = mul(ret, B);
ins(ret);
}
for(int i = 0; i < m; i++){
for(int j = 0; j < m; j++){
printf("%d%c", ret.s[i][j], j == m - 1? '\n' : ' ');
}
}
}
return 0;
}