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算法的更多相关文章

  1. Berlekamp_Massey 算法 (BM算法) 学习笔记

    原文链接www.cnblogs.com/zhouzhendong/p/Berlekamp-Massey.html 前言 BM算法用于求解常系数线性递推式. 它可以在 $O(n^2)$ 的时间复杂度内解 ...

  2. 字符串匹配算法(二)-BM算法详解

    我们在字符串匹配算法(一)学习了BF算法和RK算法,那有没更加高效的字符串匹配算法呢.我们今天就来聊一聊BM算法. BM算法 我们把模式串和主串的匹配过程,可以看做是固定主串,然后模式串不断在往后滑动 ...

  3. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  4. hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)

    基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...

  5. [置顶] 小白学习KM算法详细总结--附上模板题hdu2255

    KM算法是基于匈牙利算法求最大或最小权值的完备匹配 关于KM不知道看了多久,每次都不能完全理解,今天花了很久的时间做个总结,归纳以及结合别人的总结给出自己的理解,希望自己以后来看能一目了然,也希望对刚 ...

  6. BM算法详解

    http://www-igm.univ-mlv.fr/~lecroq/string/node14.html http://www.cs.utexas.edu/users/moore/publicati ...

  7. 学习cordic算法所得(流水线结构、Verilog标准)

    最近学习cordic算法,并利用FPGA实现,在整个学习过程中,对cordic算法原理.FPGA中流水线设计.Verilog标准有了更加深刻的理解. 首先,cordic算法的基本思想是通过一系列固定的 ...

  8. Boyer-Moore(BM)算法,文本查找,字符串匹配问题

    KMP算法的时间复杂度是O(m + n),而Boyer-Moore算法的时间复杂度是O(n/m).文本查找中“ctrl + f”一般就是采用的BM算法. Boyer-Moore算法的关键点: 从右遍历 ...

  9. 【算法】BM算法

    目录 BM算法 一. 字符串比较的分析 二.BM算法的思想 三.算法实现 BM算法 @ 一. 字符串比较的分析 如果要判定长度为\(n\)两个字符串相等,比较中要进行\(n\)比较,但是如果要判定两个 ...

随机推荐

  1. MySQL inodb cluster部署

    innodb cluster是基于组复制来实现的. 搭建一套MySQL的高可用集群innodb. 实验环境: IP 主机名 系统 软件 192.168.91.46 master RHEL7.4 mys ...

  2. 在树莓派4b上安装 ROS MELODIC 源码安装

    按照以下步骤照做就可以了,很简单的,就是浪费一点点时间罢了.也可以退而求其次,买个树莓派3B+来玩,哈哈. Step 1: Install Dependecies and Download the P ...

  3. ubuntu 16.04 脚本开机自启动

    1.首先编写一个shell脚本文件,例如python_self_start.sh (nohup & 指定后台运行) #!/bin/bash nohup python3 /home/senset ...

  4. 从Maven中央仓库下载jar包

    1. Maven中央仓库 Maven中央仓库存放着比较新版本比较全的 jar 包 仓库网址:https://mvnrepository.com/ 2. 使用Maven中央仓库的 jar 包 (1) 在 ...

  5. sass/scss 和 less对比

    一. Sass/Scss.Less是什么? Sass (Syntactically Awesome Stylesheets)是一种动态样式语言,Sass语法属于缩排语法,比css比多出好些功能(如变量 ...

  6. Django中的 返回json对象的方式

    在返回json对象的几种方式: 1 from django.shortcuts import render, HttpResponse # Create your views here. from d ...

  7. 前端知识点回顾——Reactjs

    React.js 编写react需要安装的三个开发环境下的模块 babel 解析JSX react 实现ui用户界面 react-dom 处理dom JSX:在JavaScript里面写html代码( ...

  8. C之交换数据案例

    //值传递 void swap(int i,int j){ printf("交换后:\n "); int tmp; tmp = i; i = j; j = tmp; } //引用传 ...

  9. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_01-页面静态化需求分析

    上半部分就是静态化 业务流程如下: 1.获取模型数据 2.制作模板 3.对页面进行静态化 4.将静态化生成的html页面存放文件系统中 5.将存放在文件系统的html文件发布到服务器

  10. django.template.exceptions.TemplateDoesNotExist: index.html

    django.template.exceptions.TemplateDoesNotExist: index.html 在网上查了下,setting中 TEMPLATES 的 'DIRS' 需要添加o ...