hdu6172&&hdu6185&&P5487——BM算法
hdu6172
模板的简单应用
先根据题中的表达式求出前几项,再上BM,注意一下n的大小关系。
#include <bits/stdc++.h> using namespace std;
#define rep(i,a,n) for (long long i=a;i<n;i++)
#define per(i,a,n) for (long long 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) ((long long)(x).size())
typedef vector<long long> VI;
typedef long long ll;
typedef pair<long long,long long> PII;
const ll mod=1e9+;
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;}
// head long long _,n;
namespace linear_seq
{
const long long N=;
ll res[N],base[N],_c[N],_md[N]; vector<long long> Md;
void mul(ll *a,ll *b,long long 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 (long long 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];
}
long long solve(ll n,VI a,VI b)
{ // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
// printf("%d\n",SZ(b));
ll ans=,pnt=;
long long 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 (long long p=pnt;p>=;p--)
{
mul(res,res,k);
if ((n>>p)&)
{
for (long long 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(,);
long long 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;
}
long long 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)));
}
}; int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%lld", &n);
n--;
/*求第n项*/
printf("%I64d\n",linear_seq::gao(VI{,,,,,,,,},n-)); }
}
hdu6185
模板的简单应用,先写个暴力程序找出前几项,可见 铺砖问题
#include <bits/stdc++.h> using namespace std;
#define rep(i,a,n) for (long long i=a;i<n;i++)
#define per(i,a,n) for (long long 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) ((long long)(x).size())
typedef vector<long long> VI;
typedef long long ll;
typedef pair<long long,long long> PII;
const ll mod=1e9+;
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;}
// head long long _,n;
namespace linear_seq
{
const long long N=;
ll res[N],base[N],_c[N],_md[N]; vector<long long> Md;
void mul(ll *a,ll *b,long long 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 (long long 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];
}
long long solve(ll n,VI a,VI b)
{ // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
// printf("%d\n",SZ(b));
ll ans=,pnt=;
long long 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 (long long p=pnt;p>=;p--)
{
mul(res,res,k);
if ((n>>p)&)
{
for (long long 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(,);
long long 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;
}
long long 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)));
}
}; int main()
{ while(scanf("%lld", &n) == )
{
/*求第n项*/
printf("%I64d\n",linear_seq::gao(VI{,,,,,,,},n-)); }
}
hdu6198
模板的简单应用
先写一个爆搜找出前几项,
#include<bits/stdc++.h>
using namespace std; const int maxn = + ;
bool vis[maxn];
int k;
int f[] = {,,,,,,,,,,,,,,,,,,,}; bool dfs(int n, int cnt)
{
//printf("%d\n", n);
if(n == && cnt == k) return true;
if(cnt == k) return false;
for(int i = ;i < && f[i] <= n; i++)
{
if(dfs(n - f[i], cnt+)) return true; //有一个满足条件的分解即可返回
}
return false;
} int main()
{
for(k = ;k < ;k++)
for(int i = ;i < ;i++)
{
if(!dfs(i, ))
{
printf("%d %d\n",k, i);
break;
}
} return ;
}
能很快找出前7项,这道题中够了。
#include <bits/stdc++.h> using namespace std;
#define rep(i,a,n) for (long long i=a;i<n;i++)
#define per(i,a,n) for (long long 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) ((long long)(x).size())
typedef vector<long long> VI;
typedef long long ll;
typedef pair<long long,long long> PII;
const ll mod=;
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;}
// head long long _,n;
namespace linear_seq
{
const long long N=;
ll res[N],base[N],_c[N],_md[N]; vector<long long> Md;
void mul(ll *a,ll *b,long long 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 (long long 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];
}
long long solve(ll n,VI a,VI b)
{ // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
// printf("%d\n",SZ(b));
ll ans=,pnt=;
long long 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 (long long p=pnt;p>=;p--)
{
mul(res,res,k);
if ((n>>p)&)
{
for (long long 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(,);
long long 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;
}
long long 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)));
}
}; int main()
{ while(scanf("%lld", &n) == )
{
/*求第n项*/
printf("%I64d\n",linear_seq::gao(VI{, , , , , , },n-)); // VI res = linear_seq::BM(VI{4, 12, 33, 88, 232, 609, 1596});
// for(int i = 1;i < res.size();i++) printf("%lld\n", (mod-res[i]) % mod);
}
}
要求输出递推式和第 $m$ 项,
可能用来验板子(单组,$ 1 \leq n \leq 1000, m\leq 10^9 $,时限3.5s,不开O2会T,应该是vector的原因吧)
#include <bits/stdc++.h> using namespace std;
#define rep(i,a,n) for (long long i=a;i<n;i++)
#define per(i,a,n) for (long long 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) ((long long)(x).size())
typedef vector<long long> VI;
typedef long long ll;
typedef pair<long long,long long> PII;
const ll mod=;
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;}
// head long long _,n;
namespace linear_seq
{
const long long N=;
ll res[N],base[N],_c[N],_md[N]; vector<long long> Md;
void mul(ll *a,ll *b,long long 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 (long long 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];
}
long long solve(ll n,VI a,VI b)
{ // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
// printf("%d\n",SZ(b));
ll ans=,pnt=;
long long 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 (long long p=pnt;p>=;p--)
{
mul(res,res,k);
if ((n>>p)&)
{
for (long long 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(,);
long long 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;
}
long long 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)));
}
}; int main()
{
int k;
vector<ll>tmp;
scanf("%d%lld", &k, &n);
for(int i = ;i < k;i++)
{
ll t;
scanf("%lld", &t);
tmp.push_back(t);
} /*输出系数*/
/*前k项递推,需要2*k项能确定*/
VI res = linear_seq::BM(tmp);
for(int i = ;i < res.size();i++) printf("%lld%c", (mod-res[i]) % mod, i == res.size()- ? '\n' : ' '); /*输出第n项*/
printf("%lld\n",linear_seq::gao(tmp, n)); }
参考链接:
1. https://blog.csdn.net/Anxdada/article/details/77817850
2. https://blog.csdn.net/WilliamSun0122/article/details/77926806
hdu6172&&hdu6185&&P5487——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 ...
- BM算法详解
http://www-igm.univ-mlv.fr/~lecroq/string/node14.html http://www.cs.utexas.edu/users/moore/publicati ...
- Boyer-Moore(BM)算法,文本查找,字符串匹配问题
KMP算法的时间复杂度是O(m + n),而Boyer-Moore算法的时间复杂度是O(n/m).文本查找中“ctrl + f”一般就是采用的BM算法. Boyer-Moore算法的关键点: 从右遍历 ...
- Berlekamp_Massey 算法 (BM算法) 学习笔记
原文链接www.cnblogs.com/zhouzhendong/p/Berlekamp-Massey.html 前言 BM算法用于求解常系数线性递推式. 它可以在 $O(n^2)$ 的时间复杂度内解 ...
- 【算法】BM算法
目录 BM算法 一. 字符串比较的分析 二.BM算法的思想 三.算法实现 BM算法 @ 一. 字符串比较的分析 如果要判定长度为\(n\)两个字符串相等,比较中要进行\(n\)比较,但是如果要判定两个 ...
- BM算法
BM算法 用来求解一个数列的递推式. 即给定\(\{x_i\}\)求解一个\(\{a_i\}\),满足\(|a|=m,x_n=\sum_{i=1}^ma_i*x_{n-i}\). 考虑增量法构造. 假 ...
- 数据结构 BM算法
BM算法是比KMP算法更快的字符串模式匹配算法.BM算法最好情况下的时间复杂度是O(n),KMP算法最好情况下的时间复杂度是O(n+m),两者最坏情况下的时间复杂度均是O(m*n).其中,n指目标串长 ...
- BM算法--串匹配
BM(Boyer-Moore)算法,后缀匹配,是指模式串的比较从右到左,模式串的移动也是从左到右的匹配过程,一般情况比KMP算法要快.时间复杂度O(m/n) C++描述(教师版) int BM(cha ...
随机推荐
- redis常用命令及持久化机制
redis 常用命令 查找redis服务文件 find / -name redis-server 查找配置文件 find / -name redis.conf 启动服务时候,要指定配置文件 启动r ...
- 如何将Prometheus仪表板添加到Grafana
Grafana是可视化的时间序列的基础设施和应用程序指标领先的图形和仪表盘构建的,但在许多其他领域,包括工业传感器,家庭自动化,天气和过程控制使用.它为您的团队和全世界提供了一种强大而优雅的方式来创建 ...
- tomcat启动时报No rules found matching 'Server/Service/Engine/Host/context'
tomcat是8.0版本. 在eclipse启动时,第二行报这个, 同时项目也没加载(tomcat启动成功了). 网上搜了半天, 试了半天, 没搞定. 最后不经意间发现: <Context do ...
- 洛谷--P1028 数的计算(递推)
题意:链接:https://www.luogu.org/problem/P1028 先输入一个自然数n (n≤1000) , 然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自 ...
- Go基础编程实践(三)—— 日期和时间
日期和时间 package main import ( "fmt" "time" ) func main() { // 获取当前时间 current := ti ...
- Python 基础-import 与 from...import....
简单说说python import与from-import- 在python用import或者from-import来导入相应的模块.模块其实就一些函数和类的集合文件,它能实现一些相应的功能,当我们需 ...
- C# vb .net实现锐化效果滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的锐化效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...
- SpringBoot的入门程序
1. 创建一个springboot工程 可以参考springboot入门程序 2. 创建一个实体类 @Data //想相当于@Setter.@Getter和@ToString替代了setter.get ...
- Kubernetes第十一章--部署微服务电商平台
- 作用域插槽模板迭代的次数,取决于组件内部独立slot的数量
第一种情况:内部有两个独立插槽(模板自动迭代2次) <!DOCTYPE html> <html> <head> <title> hello world ...