Index: lib/numeric/matrix.cpp ================================================================== --- lib/numeric/matrix.cpp +++ lib/numeric/matrix.cpp @@ -1,55 +1,118 @@ - //------------------------------------------------------------- // Matrix Operations // // Verified by // - SRM342 Div1 LV3 // - SRM341 Div1 LV3 // - SRM338 Div1 LV2 //------------------------------------------------------------- -vector vMul( const vector< vector >& A, const vector& B ) +template +vector MATMUL(const vector< vector >& a, const vector& v) +{ + int N = a.size(); + vector u(N); + for(int i=0; i +vector< vector > MATMUL(const vector< vector >& a, const vector< vector >& b) +{ + int N = a.size(); + vector< vector > c(N, vector(N)); + for(int i=0; i +vector MATPOWMUL(vector< vector > a, LL e, vector v) { - const int n = A.size(); - - vector C(n); - for(int i=0; i>=1, a=MATMUL(a,a)) + if(e&1) + v = MATMUL(a, v); + return v; } -vector< vector > mMul( const vector< vector >& A, const vector< vector >& B ) +template +vector< vector > MATPOW(vector< vector > a, LL e) { - const int n = A.size(); - - vector< vector > C(n, vector(n)); - for(int i=0; i > c(N, vector(N)); + for(int i=0; i>=1) { + if(e&1) + c = MATMUL(c, a); + a = MATMUL(a, a); + } + return c; } -vector< vector > mPow( vector< vector > M, LL t ) // t>0 -{ - vector< vector > R; - for(; t; t>>=1, M=mMul(M,M)) - if( t&1 ) - R = (R.empty() ? M : mMul(R,M)); - return R; -} +/**************************************************************************** + NOTES ON THE USAGE + **************************************************************************** + +A[to][from] = #transition +-------------------------------------------- + + frm + (. . .) (q0) +to (. . .) (q1) + (. . .) (q2) + + + +ƒ° qi +-------------------------------------------- + + frm + (. . . 0) (.) +to (. . . 0) (.) + (. . . 0) (.) + (0 1 0 1) (0) + ^ + i +Then, + q[i]@0 = (A^1 v)[$-1] + q[i]@0 + q[i]@1 = (A^2 v)[$-1] + q[i]@0 + ... + q[i]@k = (A^(k+1) v)[$-1] + + + +ƒ° q_all +-------------------------------------------- + + frm + (. . . 0) (.) +to (. . . 0) (.) + (. . . 0) (.) + (1 1 1 1) (0) + +Then, + ƒ°q @0 = (A^1 v)[$-1] + ƒ°q @0 + ... + ƒ°q @k = (A^(k+1) v)[$-1] + + + + + +Application: x^0 + x^1 + ... + x^e-1 +-------------------------------------------- + + (x 0)^e (1) = (x^e ) + (1 1) (0) (x^0 + x^1 + ... + x^e-1) + + -vector< vector > mAdd( const vector< vector >& A, const vector< vector >& B ) -{ - const int n = A.size(); +Application: e x^0 + (e-1) x^1 + ... + 1 x^e-1 +-------------------------------------------- - vector< vector > C(n, vector(n)); - for(int i=0; i>=1) if(e&1) v*=x; return v; } mint& operator/=(mint& x, mint y) { return x *= POW(y, MODVAL-2); } mint operator/(mint x, mint y) { return x/=y; } -// nCk :: O(log MODVAL) time, O(n) space. vector FAC_(1,1); mint FAC(LL n) { while( FAC_.size()<=n ) FAC_.push_back( FAC_.back()*FAC_.size() ); return FAC_[n]; } + +// nCk :: O(log MODVAL) time, O(n) space. mint C(LL n, LL k) { return k<0 || n > CP_; mint C(LL n, LL k) { @@ -42,81 +44,12 @@ CP_[nn][kk] = CP_[nn-1][kk-1] + CP_[nn-1][kk]; } return k<0 || n -vector MATMUL(const vector< vector >& a, const vector& v) +// O(log MODVAL), MODVAL must be prime: k^b + k^b+1 + ... + k^e +mint GSS(mint k, LL b, LL e) { - int N = a.size(); - vector u(N); - for(int i=0; i e ) return 0; + if( k.val <= 1 ) return k*(e-b+1); + return (POW(k, e+1) - POW(k,b)) / (k-1); } - -template -vector< vector > MATMUL(const vector< vector >& a, const vector< vector >& b) -{ - int N = a.size(); - vector< vector > c(N, vector(N)); - for(int i=0; i -vector< vector > MATPOW(vector< vector > a, LL e) -{ - int N = a.size(); - vector< vector > c(N, vector(N)); - for(int i=0; i>=1) { - if(e&1) - c = MATMUL(c, a); - a = MATMUL(a, a); - } - return c; -} - -/* -// MODVAL must be a prime!! -LL GSS(LL k, LL b, LL e) // k^b + k^b+1 + ... + k^e -{ - if( b > e ) return 0; - if( k <= 1 ) return k*(e-b+1); - return DIV(SUB(POW(k, e+1), POW(k,b)), k-1); -} - -// works for non-prime MODVAL -LL GEO(LL x_, LL e) // x^0 + x^1 + ... + x^e-1 -{ - vector< vector > v(2, vector(2)); - vector< vector > x(2, vector(2)); - v[0][0] = v[1][1] = 1; - x[0][0] = x_; x[0][1] = 0; - x[1][0] = 1 ; x[1][1] = 1; - for(;e;x=MATMUL(x,x),e>>=1) - if(e&1) - v = MATMUL(v, x); - return v[1][0]; -} - -// works for non-prime MODVAL -LL HYP(LL x_, LL e) // e x^0 + (e-1) x^1 + ... + 1 x^e-1 = GEO(x,1)+GEO(x,2)+...+GEO(x,e) -{ - vector< vector > v(3, vector(3)); - vector< vector > x(3, vector(3)); - v[0][0] = v[1][1] = v[2][2] = 1; - x[0][0] = x_; x[0][1] = 0; x[0][2] = 0; - x[1][0] = 1 ; x[1][1] = 1; x[1][2] = 0; - x[2][0] = 0 ; x[2][1] = 1; x[2][2] = 1; - e++; - for(;e;x=MATMUL(x,x),e>>=1) - if(e&1) - v = MATMUL(v, x); - return v[2][0]; -} -*/