题目大意
给你$n$个矩阵,回答模$r$下$m$个区间内矩阵的乘积。
简要题解
分块傻题。
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace my_header { 4 #define pb push_back 5 #define mp make_pair 6 #define pir pair<int, int> 7 #define vec vector<int> 8 #define pc putchar 9 #define clr(t) memset(t, 0, sizeof t) 10 #define pse(t, v) memset(t, v, sizeof t) 11 #define bl puts("") 12 #define wn(x) wr(x), bl 13 #define ws(x) wr(x), pc(' ') 14 const int INF = 0x3f3f3f3f; 15 typedef long long LL; 16 typedef double DB; 17 inline char gchar() { 18 char ret = getchar(); 19 for(; (ret == ' ' || ret == ' ' || ret == ' ') && ret != EOF; ret = getchar()); 20 return ret; } 21 template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) { 22 for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar()); 23 if (c == '-') { flg = -1; c = getchar(); } 24 for(ret = 0; '0' <= c && c <= '9'; c = getchar()) 25 ret = ret * 10 + c - '0'; 26 ret = ret * flg; } 27 inline int fr() { int t; fr(t); return t; } 28 template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); } 29 template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); } 30 template<class T> inline char wr(T a, int b = 10, bool p = 1) { 31 return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 32 (wr(a/b, b, 0), pc('0' + a % b))); 33 } 34 template<class T> inline void wt(T a) { wn(a); } 35 template<class T> inline void wt(T a, T b) { ws(a), wn(b); } 36 template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); } 37 template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); } 38 template<class T> inline T gcd(T a, T b) { 39 return b == 0 ? a : gcd(b, a % b); } 40 template<class T> inline T fpw(T b, T i, T _m, T r = 1) { 41 for(; i; i >>= 1, b = b * b % _m) 42 if(i & 1) r = r * b % _m; 43 return r; } 44 }; 45 using namespace my_header; 46 47 const int MAXN = 30000 + 100; 48 const int NBLK = 200; 49 int r, n, m; 50 51 struct Matrix { 52 int d[2][2]; 53 Matrix() { 54 memset(d, 0, sizeof d); 55 } 56 int *operator [] (int a) { 57 return d[a]; 58 } 59 void read() { 60 fr(d[0][0], d[0][1]); 61 fr(d[1][0], d[1][1]); 62 } 63 } mat[MAXN], blk[400]; 64 Matrix operator * (Matrix a, Matrix b) { 65 Matrix c; 66 for (int i = 0; i < 2; ++i) 67 for (int j = 0; j < 2; ++j) 68 for (int k = 0; k < 2; ++k) 69 (c[i][j] += a[i][k] * b[k][j]) %= r; 70 return c; 71 } 72 73 int main() { 74 #ifdef lol 75 freopen("B.in", "r", stdin); 76 freopen("B.out", "w", stdout); 77 #else 78 freopen("crypto.in", "r", stdin); 79 freopen("crypto.out", "w", stdout); 80 #endif 81 82 fr(r, n, m); 83 int cb = 0; 84 blk[cb][0][0] = blk[cb][1][1] = 1; 85 for (int i = 1; i <= n; ++i) { 86 if ((i - 1) % NBLK == 0) { 87 ++cb; 88 blk[cb][0][0] = blk[cb][1][1] = 1; 89 } 90 mat[i].read(); 91 blk[cb] = blk[cb] * mat[i]; 92 } 93 while (m--) { 94 int l, r; 95 fr(l, r); 96 Matrix ret; 97 ret[0][0] = ret[1][1] = 1; 98 for (int j = l; j <= r; ++j) { 99 if (j % NBLK == 1 && j + 199 <= r) { 100 ret = ret * blk[j / NBLK + 1]; 101 j += 199; 102 } else { 103 ret = ret * mat[j]; 104 } 105 } 106 wt(ret[0][0], ret[0][1]); 107 wt(ret[1][0], ret[1][1]); 108 bl; 109 } 110 111 return 0; 112 }