Rapid matrix power, Matrix
Training little cats
| Time Limit:2000 MS |
|
Memory Limit:65536 K |
| Total Submissions:9785 |
|
Accepted:2340 |
Description
Facer's pet cat just gave birth to a brood of little cats. having considered the health of those lovely cats, Facer decides to make the cats to do some exercises. facer has well designed a set of moves for his cats. he is now asking you to supervise the cats to do his exercises. facer's great exercise for cats contains three different moves:
G I: Let the ith cat take a peanut.
E I: Let the ith cat eat all peanuts it have.
S I j: Let the ith cat and jth cat exchange their peanuts.
All the cats perform a sequence of these moves and must repeat it m times! Poor cats! Only Facer can come up with such embarrassing idea.
You have to determine the final number of peanuts each cat have, and directly give them the exact quantity in order to save them.
Input
The input file consists of multiple test cases, ending with three zeroes "0 0 0". For each test case, three integersN,MAndKAre given firstly, whereNIs the number of cats andKIs the length of the move sequence. The followingKLines describe the sequence.
(M≤ 1,000,000,000,N≤ 100,K≤ 100)
Output
For each test case, outputNNumbers in a single line, representing the numbers of peanuts the cats have.
Sample Input
3 1 6g 1g 2g 2s 1 2g 3e 20 0 0
Sample Output
2 0 1
Source
PKU Campus 2009 (POJ Monthly Contest-2009.05.17), Facer
Matrix Quick power template, using some properties of the matrix
1) ABC = A (BC). Therefore, to process A matrix, you only need to process the following m matrices, A vector matrix is actually used to obtain the n-1 elements of the last row. Therefore, we can ignore it and use a loop to process the last row;
2) when changing the matrix, we assume that a vector matrix (x, y, z) is the result we need. When dealing with switching and elimination of 0, processing of the matrix of units is very simple, but when processing addition, an additional one will appear in the diagonal p [n] [n], and an error will occur when accumulating, therefore, we need to expand the matrix size by 1. In this way, changing values of x, y, and z will not be affected during matrix processing.
3) High-Speed Power pruning: Generally, when we use the binary method for pruning to process a special data structure such as a matrix, we can see if it is a sparse matrix when two matrices are multiplied, if it is a sparse or sparse matrix, you can change the order of Matrix Multiplication. For example, it may be easy to understand:
1 2 3 1 2 3 1*1*2 1*3
4 5 6*4 5 6 = 4*1 4*2 4*3
67 8 6 7 8 6*1 6*2 6*3. During the multiplication, the values are not added at one time, but respectively. The red values are considered as queues, and there is a number of strings in them, each number in each row is added to each column, as long as the number of the previous matrix is 0, therefore, the column corresponding to this number is 0 in the current situation.
In fact, the above is an explanation of the template, because this is a very common template question.
Code:
# Include <stdio. h> # include <string. h> int n; struct cat {__ int64 v [110] [110]; cat () {memset (v, 0, sizeof (v ));}}; cat Mul_M_M (cat p, cat q) {cat t; for (int I = 0; I <= n; I ++) for (int j = 0; j <= n; j ++) if (p. v [I] [j]) for (int k = 0; k <= n; k ++) t. v [I] [k] + = p. v [I] [j] * q. v [j] [k]; return t;} void Mul_MM (cat p, int x) {cat t; for (int I = 0; I <= n; I ++) t. v [I] [I] = 1; while (x) {if (x & 1) {t = Mul_M_M (t, p);} p = Mul_M_M (p, p); x> = 1 ;}for (int I = 0; I <n-1; I ++) printf ("% I64d", t. v [n] [I]); printf ("% I64d \ n", t. v [n] [n-1]);} int main () {int m, k; char a [2]; int d, c; while (scanf ("% d", & n, & m, & k), n | m | k) {cat p; for (int I = 0; I <= n; I ++) p. v [I] [I] = 1; for (int I = 0; I <k; I ++) {scanf ("% s", ); switch (a [0]) {case 'G': scanf ("% d", & d); p. v [n] [D-1] ++; break; // Add one; case 'E': scanf ("% d", & d); for (int j = 0; j <= n; j ++) p. v [j] [D-1] = 0; // qing0break; case's ': scanf ("% d", & c, & d ); for (int j = 0; j <= n; j ++) {int t = p. v [j] [C-1]; p. v [j] [C-1] = p. v [j] [D-1]; p. v [j] [D-1] = t;} // jiaohuan break;} Mul_MM (p, m );}}
Rapid power of Matrix Multiplication
A ^ 2 k = (A ^ 2) ^ k, A ^ (2 k + 1) = (A ^ 2) ^ k *
That is, for n scale, it can be converted to n/2.
The following is a program for getting the remainder of the nth entry of the Fibonacci series in the matrix's fast power solution, but it always runs an error.
According to the normal logic, only a [2] [2] = {1, 1, 1, 0} The n (a [0] [1]) of the Fibonacci series can be obtained from the Npower of the matrix. However, if you ignore this, you are requesting a [0] [1], a [1] [0], when you set the value of a [1] [1], your value of a [0] [0] has actually changed, as a result, the value of a [0] [1] You obtained is incorrect, which affects the values of a [1] [0] And a [1] [1.
Therefore, when traversing these four values, we cannot change any of them. We can only change the value after the change. Therefore, we can use several variables to first store the obtained new matrix values, as shown below:
# Include <stdio. h>
Int a [2] [2] = {1, 1, 0}, B [2] [2] = {1, 1, 0 }; // use two-dimensional arrays to represent the matrix used by the fast power algorithm
Int main ()
{
Int n, m, I, j, t, u;
Int a1, a2, a3, a4;
While (scanf ("% d", & n, & m )! = EOF)
{
If (m =-1 & n =-1) // end the entire algorithm when the input m. n value is-1.
Return 0;
/* The following is the calculation of the nth Fibonacci number */
If (n = 0)
A [0] [0] = 0;
Else if (n = 1 | n = 2)
A [0] [0] = 1;
Else
{
For (I = 3; I <= n; I ++)
{
A1 = a [0] [0] * B [0] [0] + a [0] [1] * B [1] [0];
A2 = a [0] [0] * B [0] [1] + a [0] [1] * B [1] [1];
A3 = a [1] [0] * B [0] [0] + a [1] [1] * B [1] [0];
A4 = a [1] [0] * B [0] [1] + a [1] [1] * B [1] [1];
A [0] [0] = a1;
A [0] [1] = a2;
A [1] [0] = a3;
A [1] [1] = a4;
}
}
T = a [0] [0];
A [0] [0] = 1; // resets the matrix.
A [0] [1] = 1;
A [1] [0] = 1;
A [1] [1] = 0;
If (m = 0)
A [0] [0] = 0;
Else if (m = 1 | m = 2)
A [0] [0] = 1;
Else
{
For (j = 3; j <= m; j ++)
{
A1 = a [0] [0] * B [0] [0] + a [0] [1] * B [1] [0];
A2 = a [0] [0] * B [0] [1] + a [0] [1] * B [1] [1];
A3 = a [1] [0] * B [0] [0] + a [1] [1] * B [1] [0];
A4 = a [1] [0] * B [0] [1] + a [1] [1] * B [1] [1];
A [0] [0] = a1;
A [0] [1] = a2;
A [1] [0] = a3;
A [1] [1] = a4;
}
}
U = a [0] [0];
A [0] [0] = 1; // resets the matrix.
A [0] [1] = 1;
A [1] [0] = 1;
A [1] [1] = 0;
T = t % u;
Printf ("% d \ n", t );
}
Return 0;
}
Another point is that the two items after the multiplication of your matrix are wrong. Let's make a comparison.
In this way, you can get the desired result.
... Remaining full text>