Youthful-Passion-Fruit-teambook

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

View the Project on GitHub AlexanderNekrasov/Youthful-Passion-Fruit-teambook

:warning: math/BerlekampMassey.cpp

Code

/**
 * Author: Igor Markelov (stole from Red Panda teambook)
 * Date: 2022-11-18
 * Description: Find the shortest linear-feedback shift register
 * Time: O(n^2)
 */
vector<int> berlekamp(vector<int> x) {
    vector<int> ls, cur;
    int lf = 0, d = 0;
    for (int i = 0; i < x.size(); ++i) {
        ll t = 0;
        for (int j = 0; j < cur.size(); ++j) {
            t = (t + (ll) x[i - j - 1] * cur[j]) % MOD;
        }
        if ((t - x[i]) % MOD == 0)
            continue;
        if (cur.empty()) {
            cur.resize(i + 1);
            lf = i;
            d = (t - x[i]) % MOD;
            continue;
        }
        ll k = -(x[i] - t) * powmod(d, MOD - 2) % MOD;
        vector<int> c(i - lf - 1);
        c.push_back(k);
        for (auto &j : ls)
            c.push_back(-j * k % MOD);
        if (c.size() < cur.size())
            c.resize(cur.size());
        for (int j = 0; j < cur.size(); ++j) {
            c[j] = (c[j] + cur[j]) % MOD;
        }
        if (i - lf + (int)ls.size() >= (int)cur.size()) {
            tie(ls, lf, d) = make_tuple(cur, i, (t - x[i]) % MOD);
        }
        cur = c;
    }
    for (auto &i : cur)
        i = (i % MOD + MOD) % MOD;
    return cur;
}
// for a_i = 2 * a_i-1 + a_i-2 returns {2, 1}

// kth element of p/q as fps
int getkfps(vector<int> p, vector<int> q, ll k) {
    assert(q[0] != 0);
    while (k) {
        auto f = q;
        for (int i = 1; i < (int) f.size(); i += 2) {
            f[i] = sub(0, f[i]);
        }
        auto p2 = conv(p, f);
        auto q2 = conv(q, f);
        p.clear(), q.clear();
        for (int i = k % 2; i < (int) p2.size(); i += 2) {
            p.pbc(p2[i]);
        }
        for (int i = 0; i < (int)q2.size(); i += 2) {
            q.pbc(q2[i]);
        }
        k >>= 1;
    }
    return mul(p[0], inv(q[0]));
}

// vals - initials values of reccurence, c - result of belekamp on vals
int getk(const vector<int> &vals, vector<int> c, ll k) {
    int d = c.size();
    c.insert(c.begin(), MOD-1);
    while (c.back() == 0) {
        c.pop_back();
    }
    for (auto &el : c) {
        el = sub(0, el);
    }
    vector<int> p(d);
    copy(vals.begin(), vals.begin() + d, p.begin());
    p = conv(p, c);
    p.resize(d);
    return getkfps(p, c, k);
}

vector<int> getmod(vector<int> a, vector<int> md) {
    for (int i = a.size() - 1; i + 1 >= md.size(); --i) {
        int v = mul(a[i], inv(md.back()));
        for (int j = 0; j < md.size(); ++j) {
            a[i - md.size() + 1 + j] = sub(a[i - md.size() + 1 + j], mul(md[j], v));
        }
        a.pop_back();
    }
    return a;
}
#line 1 "math/BerlekampMassey.cpp"
/**
 * Author: Igor Markelov (stole from Red Panda teambook)
 * Date: 2022-11-18
 * Description: Find the shortest linear-feedback shift register
 * Time: O(n^2)
 */
vector<int> berlekamp(vector<int> x) {
    vector<int> ls, cur;
    int lf = 0, d = 0;
    for (int i = 0; i < x.size(); ++i) {
        ll t = 0;
        for (int j = 0; j < cur.size(); ++j) {
            t = (t + (ll) x[i - j - 1] * cur[j]) % MOD;
        }
        if ((t - x[i]) % MOD == 0)
            continue;
        if (cur.empty()) {
            cur.resize(i + 1);
            lf = i;
            d = (t - x[i]) % MOD;
            continue;
        }
        ll k = -(x[i] - t) * powmod(d, MOD - 2) % MOD;
        vector<int> c(i - lf - 1);
        c.push_back(k);
        for (auto &j : ls)
            c.push_back(-j * k % MOD);
        if (c.size() < cur.size())
            c.resize(cur.size());
        for (int j = 0; j < cur.size(); ++j) {
            c[j] = (c[j] + cur[j]) % MOD;
        }
        if (i - lf + (int)ls.size() >= (int)cur.size()) {
            tie(ls, lf, d) = make_tuple(cur, i, (t - x[i]) % MOD);
        }
        cur = c;
    }
    for (auto &i : cur)
        i = (i % MOD + MOD) % MOD;
    return cur;
}
// for a_i = 2 * a_i-1 + a_i-2 returns {2, 1}

// kth element of p/q as fps
int getkfps(vector<int> p, vector<int> q, ll k) {
    assert(q[0] != 0);
    while (k) {
        auto f = q;
        for (int i = 1; i < (int) f.size(); i += 2) {
            f[i] = sub(0, f[i]);
        }
        auto p2 = conv(p, f);
        auto q2 = conv(q, f);
        p.clear(), q.clear();
        for (int i = k % 2; i < (int) p2.size(); i += 2) {
            p.pbc(p2[i]);
        }
        for (int i = 0; i < (int)q2.size(); i += 2) {
            q.pbc(q2[i]);
        }
        k >>= 1;
    }
    return mul(p[0], inv(q[0]));
}

// vals - initials values of reccurence, c - result of belekamp on vals
int getk(const vector<int> &vals, vector<int> c, ll k) {
    int d = c.size();
    c.insert(c.begin(), MOD-1);
    while (c.back() == 0) {
        c.pop_back();
    }
    for (auto &el : c) {
        el = sub(0, el);
    }
    vector<int> p(d);
    copy(vals.begin(), vals.begin() + d, p.begin());
    p = conv(p, c);
    p.resize(d);
    return getkfps(p, c, k);
}

vector<int> getmod(vector<int> a, vector<int> md) {
    for (int i = a.size() - 1; i + 1 >= md.size(); --i) {
        int v = mul(a[i], inv(md.back()));
        for (int j = 0; j < md.size(); ++j) {
            a[i - md.size() + 1 + j] = sub(a[i - md.size() + 1 + j], mul(md[j], v));
        }
        a.pop_back();
    }
    return a;
}
Back to top page