Berlekamp-Massey algorithm

https://www.cnblogs.com/zzqsblog/p/6877339.html
https://blog.csdn.net/qq_39972971/article/details/80725873

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3005;
const int MOD = 1E9 + 7;

inline int Add(int a, int b) {
    return (a + b >= MOD) ? (a + b - MOD) : (a + b);
}
inline int Sub(int a, int b) {
    return (a >= b) ? (a - b) : (a - b + MOD);
}
inline int Mul(int a, int b) {
    return (LL)a * b % MOD;
}
inline int Pow(int a, int b) {
    int c = 1;
    for (; b; a = Mul(a, a), b >>= 1)
        if (b & 1) c = Mul(c, a);
    return c;
}

int n;
int a[N], b[N], c[N], d[N];

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    int m = 0, fa = 0, dt = 0, k = 0;
    for (int i = 1; i <= n; ++i) {
        int t = a[i];
        for (int j = 1; j <= m; ++j)
            t = Sub(t, Mul(b[j], a[i - j]));
        if (!t) continue;
        if (!fa) {
            k = m;
            m = i;
            fa = i;
            dt = t;
            continue;
        }
        copy(b + 1, b + m + 1, d + 1);
        int x = i - 1 - fa, v = Mul(t, Pow(dt, MOD - 2)), nm = max(m, x + k + 1);
        b[x + 1] = Add(b[x + 1], v);
        for (int j = 1; j <= k; ++j)
            b[x + j + 1] = Sub(b[x + j + 1], Mul(c[j], v));
        if (i - m > fa - k) {
            copy(d + 1, d + m + 1, c + 1);
            fa = i;
            dt = t;
            k = m;
        }
        m = nm;
    }
    // for (int i = m + 1; i <= n; ++i) {
    //     int t = a[i];
    //     for (int j = 1; j <= m; ++j)
    //         t = Sub(t, Mul(a[i - j], b[j]));
    //     if (t) {
    //         cerr << i << endl;
    //         throw;
    //     }
    // }
    printf("%d\n", m);
    for (int i = 1; i <= m; ++i)
        printf("%d ", b[i]);
    puts("");
    return 0;
}
posted @ 2019-04-17 12:22  tkandi  阅读(211)  评论(0编辑  收藏  举报