HDU 2276 Kiki & little Kiki 2 (bitwise operation + matrix power)
ACM
Address: HDU 2276 Kiki & little Kiki 2
Question:
The switch status is known in One-stop light. Every second: the I-th Light changes according to the switch on the left. If it is on the left, it changes, if it is off, it will remain in the original state. Ask about the status after M seconds.
The left side of the 1st is the last one.
Analysis:
Transfer is hard to think about...
The change is as follows:
OriginalLeftChange
-
110
101
-
011
000
Then think (~ Original) ^ (left) = change
We cannot figure out the matrix tat...
After reading other people's questions, I found that: (originally + Left) & 2 = change, instantly orz.
But that's right. What the matrix needs is addition.
Then construct the matrix. See the matrix of great gods:
-
"1 0 0... 0 1
-
1 1 0... 0 0
0 1 1... 0 0
-
0 0 1 .. 0 0
-
...........
0 0 0... 1 1
-
"
Note that if the matrix multiplication % 2 is used, the data is too large.
In this case, bitwise operations can be used for optimization.
We noticed that: (1 + 1) % 2 and 1 ^ 1 have the same results, and 1*1 and 1 & 1 have the same results, so let's change the multiplication function.
Code :
/** Author: zhangz <iw.zen [at] gmail.com> * blog: http://blog.csdn.net/hcbbt* file: 2276. CPP * Create Date: 22:47:12 * descripton: */# include <cstdio> # include <cstring> # include <iostream> # include <algorithm> # include <cmath> using namespace STD; # define repf (I,, b) For (INT I = (a); I <= (B); I ++) typedef long ll; const int size = 101; // Max size of the matrixint N; string s; struct mat {int N; int V [Size] [size]; // value of matrixmat (INT _ n = size) {n = _ n; memset (v, 0, sizeof (v ));} void Init (LL _ v) {memset (v, 0, sizeof (v); repf (I, 0, n-1) V [I] [I] = _ v;} void output () {repf (I, 0, n-1) {repf (J, 0, n-1) printf ("% d", V [I] [J]); puts ("");} puts ("") ;}} A, B, C; mat operator * (MAT a, mat B) {mat C (. n); repf (I, 0,. n-1) {repf (J, 0,. n-1) {C. V [I] [J] = 0; repf (K, 0,. n-1) {C. V [I] [J] ^ = (. V [I] [k] & B. V [k] [J]) ;}} return C;} mat operator ^ (MAT a, ll K) {mat C (. n); C. init (1); While (k) {If (K & 1) C = C * A; A = A * A; k >>=1;} return C ;} void Init () {CIN> S; int Len = S. length ();. N = B. N = C. N = Len;. init (0); B. init (0); C. init (0); repf (I, 0, len-1) {B. V [I] [0] = s [I]-'0';}. V [0] [0] =. V [0] [. n-1] = 1; repf (I, 1,. n-1) {. V [I] [I] =. V [I] [I-1] = 1 ;}} void solve (INT N) {c = a ^ (n ); C = C * B; repf (I, 0, C. n-1) {printf ("% d", C. V [I] [0]);} puts ("");} int main () {While (~ Scanf ("% d", & N) {Init (); solve (n);} return 0 ;}