模板 - 线性递推BM
模数是998244353的话好像NTT可以更快。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 3e5 + 51, MOD = 998244353, G = 3, INVG = 332748118;
int exponent, fd, cnt = 1, limit = -1, rres, ptr;
int rev[MAXN], f[MAXN], g[MAXN], tmp[MAXN], tmp2[MAXN], tmp3[MAXN], tbm[MAXN];
int res[MAXN], base[MAXN], fail[MAXN];
ll delta[MAXN];
inline int read() {
int num = 0;
bool neg = false;
char ch = getchar();
while(!isdigit(ch) && ch != '-')
ch = getchar();
if(ch == '-')
neg = true, ch = getchar();
while(isdigit(ch))
num = (num << 3) + (num << 1) + (ch - '0'), ch = getchar();
return neg ? -num : num;
}
inline int qpow(ll x, int n) {
ll res = 1;
for(; n; x = x * x % MOD, n >>= 1)
if(n & 1)
res = res * x % MOD;
return res;
}
inline void NTT(int *cp, int cnt, int inv) {
int cur = 0, res = 0;
for(int i = 0; i < cnt; i++)
if(i < rev[i])
swap(cp[i], cp[rev[i]]);
for(int i = 2; i <= cnt; i <<= 1) {
cur = i >> 1, res = qpow(inv == 1 ? G : INVG, (MOD - 1) / i);
for(int *p = cp; p != cp + cnt; p += i) {
ll w = 1;
for(int j = 0; j < cur; j++) {
int t = w * p[j + cur] % MOD, t2 = p[j];
p[j + cur] = (t2 - t + MOD) % MOD, p[j] = (t2 + t) % MOD;
w = w * res % MOD;
}
}
}
if(inv == -1) {
int invl = qpow(cnt, MOD - 2);
for(int i = 0; i <= cnt; i++)
cp[i] = (ll) cp[i] * invl % MOD;
}
}
inline void inv(int fd, int *f, int *res) {
static int tmp[MAXN];
if(fd == 1) {
res[0] = qpow(f[0], MOD - 2);
return;
}
inv((fd + 1) >> 1, f, res);
int cnt = 1, limit = -1;
while(cnt < (fd << 1))
cnt <<= 1, limit++;
for(int i = 0; i < cnt; i++) {
tmp[i] = i < fd ? f[i] : 0;
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << limit);
}
NTT(tmp, cnt, 1), NTT(res, cnt, 1);
for(int i = 0; i < cnt; i++)
res[i] = 1ll * (2 - 1ll * tmp[i] * res[i] % MOD + MOD) % MOD * res[i] % MOD;
NTT(res, cnt, -1);
for(int i = fd; i < cnt; i++)
res[i] = 0;
}
inline void mod(int *f) {
static int tmp[MAXN], q[MAXN];
int deg = fd << 1;
while(!f[--deg]);
if(deg < fd)
return;
for(int i = 0; i < cnt; i++)
tmp[i] = i <= deg ? f[i] : 0;
reverse(tmp, tmp + 1 + deg);
for(int i = deg + 1 - fd; i <= deg; tmp[i] = 0, i++);
NTT(tmp, cnt, 1);
for(int i = 0; i < cnt; q[i] = (ll)tmp[i] * tmp3[i] % MOD, i++);
NTT(q, cnt, -1);
for(int i = 0; i < cnt; tmp[i] = 0, q[i] = i <= deg - fd ? q[i] : 0, i++);
reverse(q, q + 1 + deg - fd), NTT(q, cnt, 1);
for(int i = 0; i < cnt; tmp[i] = (ll)q[i] * g[i] % MOD, i++);
NTT(tmp, cnt, -1);
for(int i = 0; i < fd; f[i] = (f[i] - tmp[i] + MOD) % MOD, i++);
for(int i = 0; i < cnt; q[i] = tmp[i] = 0, f[i] = i < fd ? f[i] : 0, i++);
}
vector<ll>bmf[MAXN];
inline void BerlekampMassey(int length, int *base, int *res) {
int cur = 0;
for(int i = 1; i <= length; i++) {
ll curr = base[i];
for(int j = 0; j < bmf[cur].size(); j++) {
curr = (curr - (ll)base[i - j - 1] * bmf[cur][j] % MOD) % MOD;
}
delta[i] = curr;
if(!delta[i]) {
continue;
}
fail[cur] = i;
if(!cur) {
bmf[++cur].resize(i), delta[i] = base[i];
continue;
}
int id = cur - 1, x = bmf[id].size() - fail[id] + i;
for(int j = 0; j < cur; j++) {
if(i - fail[j] + bmf[j].size() < x) {
id = j, x = i - fail[j] + bmf[j].size();
}
}
bmf[cur + 1] = bmf[cur], cur++;
while(bmf[cur].size() < x) {
bmf[cur].push_back(0);
}
ll mul = (ll)delta[i] * qpow(delta[fail[id]], MOD - 2) % MOD;
bmf[cur][i - fail[id] - 1] = (ll)(bmf[cur][i - fail[id] - 1] + mul) % MOD;
for(int j = 0; j < bmf[id].size(); j++) {
int t = (ll)mul * bmf[id][j] % MOD;
bmf[cur][i - fail[id] + j] = (bmf[cur][i - fail[id] + j] - t + MOD) % MOD;
}
}
ptr = cur;
for(int i = 0; i < bmf[cur].size(); i++) {
res[i + 1] = (bmf[cur][i] % MOD + MOD) % MOD;
}
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
fd = read(), exponent = read();
for(int i = 0; i < fd; i++)
tbm[i + 1] = f[i] = (read() + MOD) % MOD;
BerlekampMassey(fd, tbm, tmp);
for(int i = 1, ci = bmf[ptr].size(); i <= ci; i++)
printf("%d%c", tmp[i], " \n"[i == ci]);
for(int i = 1; i <= fd; g[fd - i] = MOD - tmp[i], i++);
g[fd] = 1;
for(int i = 0; i <= fd; i++)
tmp2[i] = g[i];
reverse(tmp2, tmp2 + 1 + fd), inv(fd << 1, tmp2, tmp3);
for(int i = 0; i <= fd; i++)
tmp2[i] = 0;
while(cnt < (fd << 2))
cnt <<= 1, limit++;
for(int i = 0; i < cnt; i++)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << limit);
NTT(g, cnt, 1), NTT(tmp3, cnt, 1), base[1] = res[0] = 1;
while(exponent) {
if(exponent & 1) {
NTT(res, cnt, 1), NTT(base, cnt, 1);
for(int i = 0; i < cnt; i++)
res[i] = (ll)res[i] * base[i] % MOD;
NTT(res, cnt, -1), NTT(base, cnt, -1), mod(res);
}
NTT(base, cnt, 1);
for(int i = 0; i < cnt; i++)
base[i] = (ll)base[i] * base[i] % MOD;
NTT(base, cnt, -1), mod(base), exponent >>= 1;
}
for(int i = 0; i < fd; i++)
rres = (rres + (ll)res[i] * f[i] % MOD) % MOD;
printf("%d\n", rres);
}
模板 - 线性递推BM的更多相关文章
- [模板]线性递推+BM
暴力版本: #include<bits/stdc++.h> #define mod 998244353 using namespace std; typedef long long int ...
- LG5487 【模板】线性递推+BM算法
[模板]线性递推+BM算法 给出一个数列 \(P\) 从 \(0\) 开始的前 \(n\) 项,求序列 \(P\) 在\(\bmod~998244353\) 下的最短线性递推式,并在 \(\bmod~ ...
- 线性递推BM模板
#include <cstdio> #include<iostream> #include <cstring> #include <cmath> #in ...
- Berlekamp Massey算法求线性递推式
BM算法求求线性递推式 P5487 线性递推+BM算法 待AC. Poor God Water // 题目来源:ACM-ICPC 2018 焦作赛区网络预赛 题意 God Wate ...
- BM求线性递推模板(杜教版)
BM求线性递推模板(杜教版) BM求线性递推是最近了解到的一个黑科技 如果一个数列.其能够通过线性递推而来 例如使用矩阵快速幂优化的 DP 大概都可以丢进去 则使用 BM 即可得到任意 N 项的数列元 ...
- 【模板】BM + CH(线性递推式的求解,常系数齐次线性递推)
这里所有的内容都将有关于一个线性递推: $f_{n} = \sum\limits_{i = 1}^{k} a_{i} * f_{n - i}$,其中$f_{0}, f_{1}, ... , f_{k ...
- HDU - 6172:Array Challenge (BM线性递推)
题意:给出,三个函数,h,b,a,然后T次询问,每次给出n,求sqrt(an); 思路:不会推,但是感觉a应该是线性的,这个时候我们就可以用BM线性递推,自己求出前几项,然后放到模板里,就可以求了. ...
- 2018 焦作网络赛 L Poor God Water ( AC自动机构造矩阵、BM求线性递推、手动构造矩阵、矩阵快速幂 )
题目链接 题意 : 实际上可以转化一下题意 要求求出用三个不同元素的字符集例如 { 'A' .'B' .'C' } 构造出长度为 n 且不包含 AAA.BBB CCC.ACB BCA.CAC CBC ...
- 牛客多校第九场 A The power of Fibonacci 杜教bm解线性递推
题意:计算斐波那契数列前n项和的m次方模1e9 题解: $F[i] – F[i-1] – F[i-2] = 0$ $F[i]^2 – 2 F[i-1]^2 – 2 F[i-2]^2 + F[i-3] ...
随机推荐
- Java验证码程序
1.设计思想利用random的随机生成数字,利用for循环控制随机数字的个数来控制验证码的输出.利用JFrame实现布局的管理,对登录框内容的位置进行管理. 2.流程图 3.源代码 denglu类 i ...
- flask_session
flask_session和Flask中的session相比,比较简单,省去了 secret_key 首先,导入flask_session 模块 from flask_session import ...
- [洛谷P4436] HNOI/AHOI2018 游戏
问题描述 一次小G和小H在玩寻宝游戏,有n个房间排成一列,编号为1,2,...,n,相邻的房间之间都有一道门.其中一部分门上锁(因此需要有对应的钥匙才能开门),其余的门都能直接打开.现在小G告诉了小H ...
- scoket、TCP、UDP、WebService选型
抱着去转型产品经理的方向去面试了一家公司,面试完很惭愧,不过见到了人事我也很意外,因为其实表现也没那么好,不过在此谈谈我的感受. 1.有3轮,前2轮都是先让我做自我介绍(我都说的很干脆,直接哪年毕业, ...
- JS中的流程控制语句
什么叫做语句? 语句:可以理解为语言中一句一句完整的话,程序是由一条条语句构成的,语句是按照自上往下的顺序执行的. 在JavaScript可以使用{ }来为语句进行分组.同一{ }中的语句称为一组 ...
- Apache简介
1.什么是Apache 注:Apache是目前使用最广泛的Web服务器软件. 2.发展历史 注:客户端mosaic程序是Netscape浏览器的前身,后来演变成mozilla浏览器,即我们使用的Fir ...
- centos apache2.4.6 apache https配置
错误描述: SSL 接收到一个超出最大准许长度的记录. 错误代码:SSL_ERROR_RX_RECORD_TOO_LONG 原因: root@iZwz93telmwbh624e5zetqZ:~# ap ...
- testlink用例转换工具2018.12版
首先说明一点,网上有很多资料,但真正可用的很少:在本人经过百度后,发现其实很多案例会因为各种原因而无法最终实现. Testlink用例转换工具,可以大致分为3种工具: 1)EX-Converter由第 ...
- 笨办法学Python(learn python the hard way)--练习程序42
下面是练习42,基于python3 #ex42.py 1 class TheThing(object): 2 #__init__为class设置内部变量的方式,正常情况下函数内的变量与外部没有关联,但 ...
- Java中的BigDecimal类和int和Integer总结
前言 我们都知道浮点型变量在进行计算的时候会出现丢失精度的问题.如下一段代码: System.out.println(0.05 + 0.01); System.out.println(1.0 - 0. ...