cplib-cpp

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub hitonanode/cplib-cpp

:heavy_check_mark: linear_algebra_matrix/test/linalg_longlong.test.cpp

Depends on

Code

#include "../linalg_longlong.hpp"
#include <iostream>
#include <numeric>
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2624"
using namespace std;

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
    for (auto &v : vec) is >> v;
    return is;
}

int main() {
    cin.tie(nullptr), ios::sync_with_stdio(false);
    using lint = long long;

    int N, T;
    cin >> N;
    vector<vector<lint>> A(N, vector<lint>(N));
    cin >> A;
    vector<lint> v(N);
    cin >> v >> T;
    A = matpower(A, T, 2);
    vector<vector<lint>> B = A;
    for (int i = 0; i < N; i++) B[i].push_back(v[i]);
    B = gauss_jordan(B, 2);
    for (int i = 0; i < N; i++) {
        if (accumulate(B[i].begin(), B[i].begin() + N, 0) == 0 and B[i][N]) {
            cout << "none\n";
            return 0;
        }
    }
    int rnk = rank_gauss_jordan(B);
    if (rnk < N) {
        cout << "ambiguous\n";
        return 0;
    }
    vector<lint> ret(N);
    for (int i = N - 1; i >= 0; i--) {
        int a = 0;
        for (int j = i + 1; j < N; j++) a += ret[j] * B[i][j];
        ret[i] = (a % 2 != B[i][N]);
    }

    for (int i = 0; i < N; i++) cout << ret[i] << (i + 1 == N ? '\n' : ' ');
}
#line 2 "number/bare_mod_algebra.hpp"
#include <algorithm>
#include <cassert>
#include <tuple>
#include <utility>
#include <vector>

// CUT begin
// Solve ax+by=gcd(a, b)
template <class Int> Int extgcd(Int a, Int b, Int &x, Int &y) {
    Int d = a;
    if (b != 0) {
        d = extgcd(b, a % b, y, x), y -= (a / b) * x;
    } else {
        x = 1, y = 0;
    }
    return d;
}
// Calculate a^(-1) (MOD m) s if gcd(a, m) == 1
// Calculate x s.t. ax == gcd(a, m) MOD m
template <class Int> Int mod_inverse(Int a, Int m) {
    Int x, y;
    extgcd<Int>(a, m, x, y);
    x %= m;
    return x + (x < 0) * m;
}

// Require: 1 <= b
// return: (g, x) s.t. g = gcd(a, b), xa = g MOD b, 0 <= x < b/g
template <class Int> /* constexpr */ std::pair<Int, Int> inv_gcd(Int a, Int b) {
    a %= b;
    if (a < 0) a += b;
    if (a == 0) return {b, 0};
    Int s = b, t = a, m0 = 0, m1 = 1;
    while (t) {
        Int u = s / t;
        s -= t * u, m0 -= m1 * u;
        auto tmp = s;
        s = t, t = tmp, tmp = m0, m0 = m1, m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

template <class Int>
/* constexpr */ std::pair<Int, Int> crt(const std::vector<Int> &r, const std::vector<Int> &m) {
    assert(r.size() == m.size());
    int n = int(r.size());
    // Contracts: 0 <= r0 < m0
    Int r0 = 0, m0 = 1;
    for (int i = 0; i < n; i++) {
        assert(1 <= m[i]);
        Int r1 = r[i] % m[i], m1 = m[i];
        if (r1 < 0) r1 += m1;
        if (m0 < m1) {
            std::swap(r0, r1);
            std::swap(m0, m1);
        }
        if (m0 % m1 == 0) {
            if (r0 % m1 != r1) return {0, 0};
            continue;
        }
        Int g, im;
        std::tie(g, im) = inv_gcd<Int>(m0, m1);

        Int u1 = m1 / g;
        if ((r1 - r0) % g) return {0, 0};

        Int x = (r1 - r0) / g % u1 * im % u1;
        r0 += x * m0;
        m0 *= u1;
        if (r0 < 0) r0 += m0;
    }
    return {r0, m0};
}

// 蟻本 P.262
// 中国剰余定理を利用して,色々な素数で割った余りから元の値を復元
// 連立線形合同式 A * x = B mod M の解
// Requirement: M[i] > 0
// Output: x = first MOD second (if solution exists), (0, 0) (otherwise)
template <class Int>
std::pair<Int, Int>
linear_congruence(const std::vector<Int> &A, const std::vector<Int> &B, const std::vector<Int> &M) {
    Int r = 0, m = 1;
    assert(A.size() == M.size());
    assert(B.size() == M.size());
    for (int i = 0; i < (int)A.size(); i++) {
        assert(M[i] > 0);
        const Int ai = A[i] % M[i];
        Int a = ai * m, b = B[i] - ai * r, d = std::__gcd(M[i], a);
        if (b % d != 0) {
            return std::make_pair(0, 0); // 解なし
        }
        Int t = b / d * mod_inverse<Int>(a / d, M[i] / d) % (M[i] / d);
        r += m * t;
        m *= M[i] / d;
    }
    return std::make_pair((r < 0 ? r + m : r), m);
}

template <class Int = int, class Long = long long> Int pow_mod(Int x, long long n, Int md) {
    static_assert(sizeof(Int) * 2 <= sizeof(Long), "Watch out for overflow");
    if (md == 1) return 0;
    Int ans = 1;
    while (n > 0) {
        if (n & 1) ans = (Long)ans * x % md;
        x = (Long)x * x % md;
        n >>= 1;
    }
    return ans;
}
#line 4 "linear_algebra_matrix/linalg_longlong.hpp"
#include <cstdlib>
#line 6 "linear_algebra_matrix/linalg_longlong.hpp"

// CUT begin
template <typename lint, typename mdint>
std::vector<std::vector<lint>> gauss_jordan(std::vector<std::vector<lint>> mtr, mdint mod) {
    // Gauss-Jordan elimination 行基本変形のみを用いるガウス消去法
    int H = mtr.size(), W = mtr[0].size(), c = 0;
    for (int h = 0; h < H; h++) {
        if (c == W) break;
        int piv = -1;
        for (int j = h; j < H; j++)
            if (mtr[j][c]) {
                if (piv == -1 or abs(mtr[j][c]) > abs(mtr[piv][c])) piv = j;
            }
        if (piv == -1) {
            c++;
            h--;
            continue;
        }
        std::swap(mtr[piv], mtr[h]);
        if (h != piv) {
            for (int w = 0; w < W; w++) {
                mtr[piv][w] =
                    mtr[piv][w] ? mod - mtr[piv][w] : 0; // To preserve sign of determinant
            }
        }
        lint pivinv = mod_inverse<lint>(mtr[h][c], mod);
        for (int hh = 0; hh < H; hh++) {
            if (hh == h) continue;
            lint coeff = mtr[hh][c] * pivinv % mod;
            for (int w = W - 1; w >= c; w--) {
                mtr[hh][w] = mtr[hh][w] - mtr[h][w] * coeff % mod;
                if (mtr[hh][w] < 0) mtr[hh][w] += mod;
            }
        }
        c++;
    }
    return mtr;
}

template <typename lint>
int rank_gauss_jordan(const std::vector<std::vector<lint>> &mtr) // Rank of Gauss-Jordan eliminated matrix
{
    for (int h = (int)mtr.size() - 1; h >= 0; h--) {
        for (auto v : mtr[h])
            if (v) return h + 1;
    }
    return 0;
}

template <typename lint, typename mdint>
lint mod_determinant(std::vector<std::vector<lint>> mtr, mdint mod) {
    if (mtr.empty()) return 1 % mod;
    assert(mtr.size() == mtr[0].size());
    lint ans = 1;
    mtr = gauss_jordan(mtr, mod);
    for (int i = 0; i < (int)mtr.size(); i++) ans = ans * mtr[i][i] % mod;
    return ans;
}

template <typename lint, typename mdint>
std::vector<std::vector<lint>>
matmul(const std::vector<std::vector<lint>> &A, const std::vector<std::vector<lint>> &B, mdint mod) {
    int H = A.size(), W = B[0].size(), K = B.size();
    std::vector<std::vector<lint>> C(H, std::vector<lint>(W));
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            for (int k = 0; k < K; k++) (C[i][j] += A[i][k] * B[k][j]) %= mod;
        }
    }
    return C;
}

template <typename lint, typename mdint>
std::vector<lint>
matmul(const std::vector<std::vector<lint>> &A, const std::vector<lint> &v, mdint mod) {
    std::vector<lint> res(A.size());
    for (int i = 0; i < (int)A.size(); i++) {
        for (int j = 0; j < (int)v.size(); j++) (res[i] += A[i][j] * v[j]) %= mod;
    }
    return res;
}

template <typename lint, typename powint, typename mdint>
std::vector<std::vector<lint>> matpower(std::vector<std::vector<lint>> X, powint n, mdint mod) {
    std::vector<std::vector<lint>> res(X.size(), std::vector<lint>(X.size()));
    for (int i = 0; i < (int)res.size(); i++) res[i][i] = 1;
    while (n) {
        if (n & 1) res = matmul(res, X, mod);
        X = matmul(X, X, mod);
        n >>= 1;
    }
    return res;
}
#line 2 "linear_algebra_matrix/test/linalg_longlong.test.cpp"
#include <iostream>
#include <numeric>
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2624"
using namespace std;

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
    for (auto &v : vec) is >> v;
    return is;
}

int main() {
    cin.tie(nullptr), ios::sync_with_stdio(false);
    using lint = long long;

    int N, T;
    cin >> N;
    vector<vector<lint>> A(N, vector<lint>(N));
    cin >> A;
    vector<lint> v(N);
    cin >> v >> T;
    A = matpower(A, T, 2);
    vector<vector<lint>> B = A;
    for (int i = 0; i < N; i++) B[i].push_back(v[i]);
    B = gauss_jordan(B, 2);
    for (int i = 0; i < N; i++) {
        if (accumulate(B[i].begin(), B[i].begin() + N, 0) == 0 and B[i][N]) {
            cout << "none\n";
            return 0;
        }
    }
    int rnk = rank_gauss_jordan(B);
    if (rnk < N) {
        cout << "ambiguous\n";
        return 0;
    }
    vector<lint> ret(N);
    for (int i = N - 1; i >= 0; i--) {
        int a = 0;
        for (int j = i + 1; j < N; j++) a += ret[j] * B[i][j];
        ret[i] = (a % 2 != B[i][N]);
    }

    for (int i = 0; i < N; i++) cout << ret[i] << (i + 1 == N ? '\n' : ' ');
}
Back to top page
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy