学习BM算法
BM算法:
希望大家别见怪,当前博客只用于个人记录所用。
【例题】Poor God Water
题意:
有肉,鱼,巧克力三种食物,有几种禁忌,对于连续的三个食物,
1.这三个食物不能都相同;
2.若三种食物都有的情况,巧克力不能在中间;
3.如果两边是巧克力,中间不能是肉或鱼。
求方案数
要求任意连续三个小时不能出现aaa,bbb,ccc,abc,cba,bab,bcb (假设b为巧克力)
然后进行推导,其实可以用矩阵快速幂 或者 BM算法。

复制粘贴一下CJY学长的代码:
#include <bits/stdc++.h> using namespace std;
typedef long long ll; const int N=;
struct Matrix{
ll matrix[N][N];
}; const int mod = 1e9 + ; void init(Matrix &res)
{
memset(res.matrix,,sizeof(res.matrix));
for(int i=;i<N;i++)
res.matrix[i][i]=;
}
Matrix multiplicative(Matrix a,Matrix b)
{
Matrix res;
memset(res.matrix,,sizeof(res.matrix));
for(int i = ; i < N ; i++){
for(int j = ; j < N ; j++){
for(int k = ; k < N ; k++){
res.matrix[i][j] += a.matrix[i][k]*b.matrix[k][j];
res.matrix[i][j] %= mod;
}
}
}
return res;
}
Matrix pow(Matrix mx,ll m)
{
Matrix res,base=mx;
init(res);
while(m)
{
if(m&)
res=multiplicative(res,base);
base=multiplicative(base,base);
m>>=;
}
return res;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll n,ant = ;
scanf("%lld",&n);
if(n == ) printf("3\n");
else if(n == ) printf("9\n");
else
{
Matrix res,ans = {
,,, ,,, ,,,
,,, ,,, ,,,
,,, ,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,,
,,, ,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,,
,,, ,,, ,,
};
res=pow(ans,n-); for(int i = ;i < N;i++)
for(int j = ;j < N;j++)
ant = (ant + res.matrix[i][j]) % mod;
printf("%lld\n",ant);
}
}
return ;
}
矩阵快速幂
#include<bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod = 1e9+;
const int N = ;
ll powmod(ll a,ll b) {
ll res=;a%=mod; assert(b>=);
for(;b;b>>=){
if(b&)res=res*a%mod;
a=a*a%mod;
}
return res;
} /*
BM模板
begin
*/ // head int _,n;
namespace linear_seq {
const int N=;
ll res[N],base[N],_c[N],_md[N]; vector<int> Md;
void mul(ll *a,ll *b,int k) {
rep(i,,k+k) _c[i]=;
rep(i,,k) if (a[i]) rep(j,,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
for (int i=k+k-;i>=k;i--) if (_c[i])
rep(j,,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
rep(i,,k) a[i]=_c[i];
}
int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
// printf("%d\n",SZ(b));
ll ans=,pnt=;
int k=SZ(a);
assert(SZ(a)==SZ(b));
rep(i,,k) _md[k--i]=-a[i];_md[k]=;
Md.clear();
rep(i,,k) if (_md[i]!=) Md.push_back(i);
rep(i,,k) res[i]=base[i]=;
res[]=;
while ((1ll<<pnt)<=n) pnt++;
for (int p=pnt;p>=;p--) {
mul(res,res,k);
if ((n>>p)&) {
for (int i=k-;i>=;i--) res[i+]=res[i];res[]=;
rep(j,,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
}
}
rep(i,,k) ans=(ans+res[i]*b[i])%mod;
if (ans<) ans+=mod;
return ans;
}
VI BM(VI s) {
VI C(,),B(,);
int L=,m=,b=;
rep(n,,SZ(s)) {
ll d=;
rep(i,,L+) d=(d+(ll)C[i]*s[n-i])%mod;
if (d==) ++m;
else if (*L<=n) {
VI T=C;
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
L=n+-L; B=T; b=d; m=;
} else {
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
++m;
}
}
return C;
}
int gao(VI a,ll n) {
VI c=BM(a);
c.erase(c.begin());
rep(i,,SZ(c)) c[i]=(mod-c[i])%mod;
return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
}
}; /*
end
*/ ll a[][],ans[]; void Init(){ int op = ;
for(int i=;i<=;i++){
a[i][op] = ;
}
for(int i=;i<=;i++){
op ^= ;
for(int j=;j<=;j++) a[j][op] = ; a[][op] = (a[][op^] + a[][op^]) % mod;
a[][op] = (a[][op^] + a[][op^]) % mod;
a[][op] = (a[][op^] + a[][op^] + a[][op^]) % mod ;
a[][op] = (a[][op^] + a[][op^]) % mod ;
a[][op] = (a[][op^] + a[][op^]) % mod ;
a[][op] = (a[][op^] + a[][op^]) % mod ;
a[][op] = (a[][op^] + a[][op^] + a[][op^]) % mod ;
a[][op] = (a[][op^] + a[][op^]) % mod ;
a[][op] = (a[][op^] + a[][op^]) % mod ; for(int j=;j<=;j++){
ans[i] = (ans[i] + a[j][op]) % mod ;
}
//printf("%lld\n",ans[i]);
}
} vector <int> Vec = { ,,,,,,,
,,,,,
,, }; int main()
{
int T; Init();
for( scanf("%d",&T) ; T ; T-- ){
ll n;
scanf("%lld",&n);
printf("%lld\n",linear_seq::gao(Vec,n-)%mod);
}
return ;
}
BM算法
牛客多校训练2 B.Eddy Walker 2
2019牛客暑期多校训练营(第二场) - B - Eddy Walker 2 - BM算法
P4723 【模板】线性递推 题解
【学习笔记】Berlekamp-Massey算法

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
typedef long long ll ;
using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef vector<ll> VI;
typedef pair<ll,ll> PII;
const ll mod = 1e9+;
const int N = 5e4+;
ll powmod(ll a,ll b) {
ll res=;a%=mod;
for(;b;b>>=){
if(b&)res=res*a%mod;
a=a*a%mod;
}
return res;
} /*
BM模板
begin
*/ // head int _,n;
namespace linear_seq {
const int N=;
ll res[N],base[N],_c[N],_md[N]; vector<int> Md;
void mul(ll *a,ll *b,int k) {
rep(i,,k+k) _c[i]=;
rep(i,,k) if (a[i]) rep(j,,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
for (int i=k+k-;i>=k;i--) if (_c[i])
rep(j,,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
rep(i,,k) a[i]=_c[i];
}
int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
// printf("%d\n",SZ(b));
ll ans=,pnt=;
int k=SZ(a);
rep(i,,k) _md[k--i]=-a[i];_md[k]=;
Md.clear();
rep(i,,k) if (_md[i]!=) Md.push_back(i);
rep(i,,k) res[i]=base[i]=;
res[]=;
while ((1ll<<pnt)<=n) pnt++;
for (int p=pnt;p>=;p--) {
mul(res,res,k);
if ((n>>p)&) {
for (int i=k-;i>=;i--) res[i+]=res[i];res[]=;
rep(j,,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
}
}
rep(i,,k) ans=(ans+res[i]*b[i])%mod;
if (ans<) ans+=mod;
return ans;
}
VI BM(VI s) {
VI C(,),B(,);
int L=,m=,b=;
rep(n,,SZ(s)) {
ll d=;
rep(i,,L+) d=(d+(ll)C[i]*s[n-i])%mod;
if (d==) ++m;
else if (*L<=n) {
VI T=C;
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
L=n+-L; B=T; b=d; m=;
} else {
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
++m;
}
}
return C;
}
int gao(VI a,ll n) {
VI c=BM(a);
c.erase(c.begin());
rep(i,,SZ(c)) c[i]=(mod-c[i])%mod;
return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
}
}; /*
end
*/
ll dp[N] ;
int main()
{
int T;
for( scanf("%d",&T) ; T ; T-- ){
memset(dp,,sizeof(dp));
ll n,k ;
VI v;
scanf("%lld%lld",&k,&n);
if( n== ){
printf("1\n");
}else if( n==- ){
printf("%lld\n",(2ll) * powmod(k+,mod-) % mod );
}else{
ll Inv_k = powmod( k ,mod-) ;
dp[] = ;
v.push_back();
for(int i=;i<=k;i++){
for(int j=;j<i;j++){
dp[i] = (dp[i] + dp[j]) % mod;
}
dp[i] = dp[i] * Inv_k % mod ;
v.push_back(dp[i]);
}
for(int i=k+;i<=*k;i++){
for(int j=;j<=k;j++){
dp[i] = (dp[i] + dp[i-j]) % mod ;
}
dp[i] = dp[i] * Inv_k % mod ;
v.push_back(dp[i]);
}
printf("%lld\n",linear_seq::gao(v,n));
}
}
return ;
}
BM
学习BM算法的更多相关文章
- Berlekamp_Massey 算法 (BM算法) 学习笔记
原文链接www.cnblogs.com/zhouzhendong/p/Berlekamp-Massey.html 前言 BM算法用于求解常系数线性递推式. 它可以在 $O(n^2)$ 的时间复杂度内解 ...
- 字符串匹配算法(二)-BM算法详解
我们在字符串匹配算法(一)学习了BF算法和RK算法,那有没更加高效的字符串匹配算法呢.我们今天就来聊一聊BM算法. BM算法 我们把模式串和主串的匹配过程,可以看做是固定主串,然后模式串不断在往后滑动 ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)
基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...
- [置顶] 小白学习KM算法详细总结--附上模板题hdu2255
KM算法是基于匈牙利算法求最大或最小权值的完备匹配 关于KM不知道看了多久,每次都不能完全理解,今天花了很久的时间做个总结,归纳以及结合别人的总结给出自己的理解,希望自己以后来看能一目了然,也希望对刚 ...
- BM算法详解
http://www-igm.univ-mlv.fr/~lecroq/string/node14.html http://www.cs.utexas.edu/users/moore/publicati ...
- 学习cordic算法所得(流水线结构、Verilog标准)
最近学习cordic算法,并利用FPGA实现,在整个学习过程中,对cordic算法原理.FPGA中流水线设计.Verilog标准有了更加深刻的理解. 首先,cordic算法的基本思想是通过一系列固定的 ...
- Boyer-Moore(BM)算法,文本查找,字符串匹配问题
KMP算法的时间复杂度是O(m + n),而Boyer-Moore算法的时间复杂度是O(n/m).文本查找中“ctrl + f”一般就是采用的BM算法. Boyer-Moore算法的关键点: 从右遍历 ...
- 【算法】BM算法
目录 BM算法 一. 字符串比较的分析 二.BM算法的思想 三.算法实现 BM算法 @ 一. 字符串比较的分析 如果要判定长度为\(n\)两个字符串相等,比较中要进行\(n\)比较,但是如果要判定两个 ...
随机推荐
- 非旋treap
目录 核心思想 核心操作 其他操作 参考程序 核心思想 主要的思想与treap是一样的.通过让二叉查找树同时满足堆(随机参数)的性质来防止深度过大.与普通treap不同的是非旋treap通过树的分裂与 ...
- 2019腾讯前端技术大会资源TWeb
扫码关注公众号 回复“TWeb”即可获取“2019腾讯前端技术大会”的PPT
- Hadoop环境搭建|第二篇:hadoop环境搭建
硬件配置:1台NameNode节点.2台DataNode节点 一.Linux环境配置 这里我只配置NameNode节点,DataNode节点的操作相同. 1.1.修改主机名 命令:vi /etc/sy ...
- smarty获得当前url的方法分享
http://{$smarty.server.SERVER_NAME}/{$smarty.server.REQUEST_URI} 注释: 复制代码代码如下: {$smarty.server.SERVE ...
- springboot整合redis(集群)
一.加入maven依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_02-vuejs研究-vuejs基础-MVVM模式
1.2.1 MVVM模式 vue.js是一个MVVM的框架,理解MVVM有利于学习vue.js. MVVM拆分解释为: Model:负责数据存储 View:负责页面展示 View Model: ...
- Centos D-Bus connection: Operation not permitted
解决办法: 首先要先在后台启动一个 CentOS7 容器(注意不要少参数): docker run -d -e "container=docker" --privileged=tr ...
- 一个可以让vsftpd启动系统用户登陆ftp的例子
编辑 /etc/vsftpd.conf 如下: listen=YES anonymous_enable=NO local_enable=YES check_shell=NO write_enable= ...
- LODOP设置纸张无效问题
有的打印机不支持自定义纸张,或不支持当前设置的纸张尺寸,会造成纸张尺寸和代码里设置的尺寸不一致的情况.现象:1.代码一样,纸张语句设置正确,有的打印机纸张正常,有的打印机不正常.2.代码一样,纸张语句 ...
- 前端如何避免bug的产生?
项目环境:react生态圈 界面功能基本和:增(新增一条数据).删(删除一条数据).查(展示列表).改(修改数据)挂钩. 一.展示数据列表相关[判空,控制显示距离,分页是否有效,搜索是否有效] 1.渲 ...