玄学小记.6 ~ Berlekamp_Massey

？？？？？

BM就是一个用来求给定数列最短线性递推的算法。
~~但是为什么这个算法找到的是最短的啊？？？？~~

$$\sum_{p = 0}^{L} \Lambda_{p} S_{k - p} = 0$$

$$\Lambda(x)S(x) \equiv M(x) \pmod { x ^ n}$$

$$C_{i - 1}(x)S(x) \equiv D_{i - 1}(x) \pmod {x^{i - 1}} 且 deg(D_{i - 1}) < deg(C_{i - 1})$$

$$C_{i}(x)S(x) \equiv D_{i}(x) \pmod {x^{i}}且 deg(D_{i}) < deg(C_{i})$$

$$C_{i - 1}(x)S(x) \equiv D_{i - 1}(x) + d x^{i - 1} \pmod {x^i}$$

$$C'_{i - 1}(x)S(x) \equiv D'_{i - 1}(x) + b x^{i - 1} \pmod {x^i}$$

$$C_{j - 1}(x)S(x) \equiv D_{j - 1}(x) + b x^{j - 1} \pmod {mod x^j} 且 b \neq 0$$

$$x^{i - j}C_{j - 1}(x)S(x) \equiv x^{i - j}D_{j - 1}(x) + b x^{i - 1}\pmod {x^i}$$

$$C_{i}(x) = C_{i - 1}(x) - \frac{d}{b}x^{i-j}C_{j-1}(x)$$

upd. 所以说要取的应该是$deg(C_{j}) - j$最小的$j$  ……

#include <bits/stdc++.h>
using namespace std;
const int L = 5000;
typedef vector <int> poly;
int p = 998244353;

void print(poly a)
{
for (int i = 0; i < a.size(); ++ i) cerr << a[i] << " "; cerr << endl;
}
int powi(int a, int b)
{
int c = 1;
for (; b; b >>= 1, a = 1ll * a * a % p)
if (b & 1) c = 1ll * c * a % p;
return c;
}
poly operator + (poly a, poly b)
{
poly c(max(a.size(), b.size()));
for (int i = 0; i < a.size(); ++ i) c[i] = a[i];
for (int i = 0; i < b.size(); ++ i) c[i] = (c[i] + b[i]) % p;
return c;
}
poly operator - (poly a, poly b)
{
poly c(max(a.size(), b.size()));
for (int i = 0; i < a.size(); ++ i) c[i] = a[i];
for (int i = 0; i < b.size(); ++ i) c[i] = (c[i] - b[i] + p) % p;
return c;
}
poly operator << (poly a, int b)
{
poly c(a.size() + b);
for (int i = 0; i < a.size(); ++ i) c[i + b] = a[i];
return c;
}
poly operator * (poly a, poly b)
{
poly c(a.size() + b.size() - 1);
for (int i = 0; i < a.size(); ++ i)
for (int j = 0; j < b.size(); ++ j)
c[i + j] = (c[i + j] + 1ll * a[i] * b[j]) % p;
return c;
}
poly conv(int t)
{
poly x(1); x[0] = t; return x;
}
poly Berlekamp_Massey(int S[], int len)
{
poly Ci = conv(1), Cj = conv(1);
int b = 1;
for (int i = 0, j = -1; i < len; ++ i)
{
int d = 0;
for (int j = 0; j < Ci.size(); ++ j)
d = (1ll * Ci[j] * S[i - j] + d) % p;
if (d)
{
poly tmp = Ci;
Ci = Ci - ((conv(1ll * d * powi(b, p - 2) % p) * Cj) << (i - j));
if ((int)Cj.size() - j > (int)tmp.size() - i)
Cj = tmp, b = d, j = i;
}
}
return Ci;
}
int X[L], len;
int main()
{
cin >> len;
for (int i = 0; i < len; ++ i) cin >> X[i];
poly T = Berlekamp_Massey(X, len);
for (int i = 0; i < T.size(); ++ i) cerr << T[i] << " "; cerr << endl;
}

posted @ 2018-06-30 21:37  AwD!  阅读(938)  评论(1编辑  收藏