BZOJ1009 单模板自动机 矩阵快速幂优化DP
来源:互联网 发布:纳粹十字勋章淘宝 编辑:程序博客网 时间:2024/06/05 13:30
第一次在BZOJ自己做出不是那么水的题,但是看这过题人数。。。嘛还是写一下题解吧
题目大意:求只由0到9组成的不包含m(m<=20)位模式串的n(n<=1e9)位字符串的个数
涉及到字符串匹配的话 很自然应该往KMP和自动机的方向想。
然后可以很容易发现建自动机可以得到一个DP做法:
定义
那么对每个
都有
那么答案就是
然后n很大 那么就矩阵快速幂吧
至此问题完美解决!
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<string>#include<iomanip>#include<vector>#include<set>#include<map>#include<queue>using namespace std;typedef long long LL;typedef unsigned long long ULL;#define rep(i,k,n) for(int i=(k);i<=(n);i++)#define rep0(i,n) for(int i=0;i<(n);i++)#define red(i,k,n) for(int i=(k);i>=(n);i--)#define sqr(x) ((x)*(x))#define clr(x,y) memset((x),(y),sizeof(x))#define pb push_backconst int maxn=100;const int maxs=10;int n,m,mod;int nxt[maxn][maxs],fail[maxn];int root,tot;int newnode(){ for(int i=0;i<maxs;i++)nxt[tot][i]=-1; return tot++;}void init(){ tot=0; root=newnode();}void insert(char str[]){ int len=strlen(str); int now=root; for(int i=0;i<len;i++) { char s=str[i]-'0'; if(nxt[now][s]==-1) nxt[now][s]=newnode(); now=nxt[now][s]; }}void build(){ queue<int> q; fail[root]=root; for(int i=0;i<maxs;i++) { if(nxt[root][i]==-1) nxt[root][i]=root; else { fail[nxt[root][i]]=root; q.push(nxt[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0;i<maxs;i++) { if(nxt[now][i]==-1) nxt[now][i]=nxt[fail[now]][i]; else { fail[nxt[now][i]]=nxt[fail[now]][i]; q.push(nxt[now][i]); } } }}struct MAT{ int a[25][25]; int n; void init(int x,int m) { clr(a,0); n=m; if(x)rep0(i,n)a[i][i]=1; } MAT operator * (const MAT &x) const { MAT ret;ret.init(0,n); rep0(i,n)rep0(j,n)rep0(k,n)(ret.a[i][j]+=a[i][k]*x.a[k][j]%mod)%=mod; return ret; } void add(int x,int y) { a[x][y]++; }};MAT quipow(MAT x,LL k){ MAT ret;ret.init(1,x.n); while(k) { if(k&1)ret=ret*x; x=x*x; k>>=1; } return ret;}char str[30];int main(){ scanf("%d%d%d",&n,&m,&mod); scanf("%s",str); init(); insert(str); build(); MAT A;A.init(0,m); rep0(i,m) { rep0(j,10) { if(nxt[i][j]!=m) { A.add(nxt[i][j],i); } } } MAT B=quipow(A,n); int ans=0; rep0(i,m)ans+=B.a[i][0]; printf("%d\n",ans%mod); return 0;}
0 0
- BZOJ1009 单模板自动机 矩阵快速幂优化DP
- bzoj1009 GT考试(AC自动机+DP+矩阵快速幂)
- bzoj1009(kmp+dp+矩阵快速幂优化)必需复习
- [BZOJ1009][HNOI2008]GT考试(AC自动机+dp+矩阵优化)
- bzoj1009[GT考试] dp+矩阵快速幂
- hdu 2243 AC自动机+dp(矩阵快速幂优化)
- bzoj1009 GT考试 KMP+矩阵优化DP
- [bzoj 1009] [HNOI2008]GT考试:DP,单串AC自动机,矩阵快速幂
- 【DP+矩阵优化】[HNOI2008][HYSBZ/BZOJ1009]GT考试
- BZOJ1009 GT考试 (DP 矩阵乘法优化)
- 【KMP+DP+矩阵优化】BZOJ1009 [HNOI2008]GT考试
- BZOJ1009: [HNOI2008]GT考试(KMP+矩阵优化DP)
- 【BZOJ1009】GT考试(HNOI2008)-DP矩阵优化+KMP
- poj 2778 DNA Sequence (ac自动机+矩阵快速幂优化dp)
- UESTC 1709 DNA序列 AC自动机+dp+矩阵快速幂优化
- POJ2778 DNA Sequence AC自动机+DP+矩阵快速幂
- poj 2778 DNA Sequence 【ac自动机 + dp + 矩阵快速幂】
- poj 2778 AC自动机+DP+矩阵快速幂
- Oracle中dual虚拟表的用途
- Oracle trunc()函数的用法
- plsql客户端连接远程和本地数据库
- em与px的区别
- 在GitHub上创建博客主页
- BZOJ1009 单模板自动机 矩阵快速幂优化DP
- 记录nginx查看启用命令
- jsp向数据库传递中文参数(变量)乱码问题的解决:
- Android开发之EditText属性详解
- android 网络获取字符串
- CSS3文本溢出显示省略号
- rabbitmq
- oracle条件分支用法 oracle 之if..else用法
- bash功能 作业控制技巧