// UVa 12045 - Fun with Strings #include <stdio.h> #include <vector> using namespace std; #define ll long ll P = 1000000007; #define MAX_N 2 struct SquareMatrix { ll mat[MAX_N][MAX_N]; }; SquareMatrix matMult(SquareMatrix a, SquareMatrix b) { // Matrix multiplication of two square matrices (N x N) SquareMatrix ans; int k, n = MAX_N; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) for (ans.mat[i][j] = k = 0; k < n; k++) { ans.mat[i][j] += a.mat[i][k] * b.mat[k][j]; //if necessary do modulo arithmetic here: ans.mat[i][j] %= P; } return ans; } SquareMatrix matPow(SquareMatrix base, int p) { // Finds base^p in O(n^3 log p) where base is a square matrix of dimensions n by n SquareMatrix ans; // prepare identity matrix int n = MAX_N; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) ans.mat[i][j] = (i == j) ? 1 : 0; // exponentiation while (p) { if (p & 1) ans = matMult(ans, base); base = matMult(base, base); p >>= 1; } return ans; } pair<ll, ll> findFibs(int n) { // Returns Fibonacci n-1 and n SquareMatrix a; a.mat[0][0] = 1; a.mat[0][1] = 1; a.mat[1][0] = 1; a.mat[1][1] = 0; SquareMatrix sol = matPow(a, n); return pair<ll, ll>(sol.mat[1][1], sol.mat[0][1]); } ll modMult(ll a, ll b) { return (a * b) % P; } ll modSum(ll a, ll b) { return (a + b) % P; } ll modSubst(ll a, ll b) { return (a + (P - b)) % P; } ll modPow(ll base, ll exponent) { if (exponent == 0) return 1; ll root = modPow(base, exponent / 2); if (exponent & 1) return modMult(modMult(root, root), base); else return modMult(root, root); } ll modDiv(ll a, ll b) { return modMult(a, modPow(b, P - 2)); } pair<ll, ll> solve(int n, int m, int x, int y) { pair<ll, ll> p = findFibs(n); ll Fn = p.second, Fn1 = (p.second + p.first) % P; p = findFibs(m); ll Fm = p.second, Fm1 = (p.second + p.first) % P; ll b1 = modSubst(modMult(x, Fm), modMult(y, Fn)); ll b2 = modSubst(modMult(Fn1, Fm), modMult(Fm1, Fn)); ll b = modDiv(b1, b2); ll a = modDiv(modSubst(y, modMult(Fm1, b)), Fm); return pair<ll, ll>(a, b); } ll lengthOf(ll k, ll a, ll b) { pair<ll, ll> p = findFibs(k); ll Fk = p.second, Fk1 = (p.second + p.first) % P; return modSum(modMult(a, Fk), modMult(b, Fk1)); } int noModLengthOf(int k, int a, int b) { pair<ll, ll> p = findFibs(k); ll Fk = p.second, Fk1 = p.second + p.first; return a * Fk + b * Fk1; } bool satisfy(int a, int b, int n, int x) { ll xx = noModLengthOf(n, a, b); return xx == x; } int main() { int cases; scanf("%d", &cases); for (; cases; cases--) { int n, x, m, y, k; scanf("%d %d %d %d %d", &n, &x, &m, &y, &k); pair<ll, ll> ab = solve(n, m, x, y); ll a = ab.first, b = ab.second; if (satisfy(a, b, n, x) && satisfy(a, b, m, y)) printf("%lld\n", lengthOf(k, ab.first, ab.second)); else printf("Impossible\n"); } return 0; }
Friday, April 24, 2015
UVa 12045 - Fun with Strings
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment