学习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\)比较,但是如果要判定两个 ...
随机推荐
- 【Python】使用Beautiful Soup等三种方式定制Jmeter测试脚本
背景介绍 我们在做性能调优时,时常需要根据实际压测的情况,调整线程组的参数,比如循环次数,线程数,所有线程启动的时间等. 如果是在一台Linux机器上,就免不了在本机打开图形页面修改,然后最后传递到压 ...
- 消息中间件MQ
消息中间件MQ:为方便预览,将思维导图上传至印象笔记,博客园直接上传图片受限于图片大小 https://app.yinxiang.com/shard/s24/nl/27262531/c3e137a5- ...
- java经典算法题50道
原文 JAVA经典算法50题[程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?1.程序 ...
- ajax调用c#后端,发现参数没数值
之前是int的数据,名字是id 后面被改成字符串的数据,名字是encrptedId 因为名字不匹配,导致找不到数值.只需要把js里调用传递的参数名字改一下,或者C#后端,继续保持原来的名字
- Understanding Models, Views, and Controllers (C#)
https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models- ...
- 使 nodejs 代码 在后端运行(forever)
情境 运行nodejs的程序,使用命令:node xxx.js,但是关掉终端,程序也关闭了,如何让node app的程序一直运行? 解决 1.安装forever npm install -g fore ...
- 《maven实战》笔记(5)----maven的版本
maven中构件和项目都有自己的版本,其中分为稳定的发布版本和不稳定的快照版本. 1.0.0.1.3-alpha-4和2.0就是稳定版本,而2.1-SNAPSHOT和2.1-20091214.2214 ...
- Android检测服务是否运行
直接上代码: /** * 判断服务是否后台运行 * * @param context * Context * @param className * 判断的服务名字 * @return true 在运行 ...
- JAVA-开发构建Gradle项目安装使用教程
一.简介: Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具.它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,目前也增加了基于Kotl ...
- CPU密集型、IO密集型
CPU密集型(CPU-bound) CPU密集型也叫计算密集型,指的是系统的硬盘.内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/ ...