首页 > 代码库 > AC日记——[HNOI2008]GT考试 bzoj 1009
AC日记——[HNOI2008]GT考试 bzoj 1009
1009
思路:
KMP上走DP(矩阵加速);
DP[i][j]表示当前在第i位,同是匹配到不吉利串的第j位的方案数;
代码:
#include <bits/stdc++.h>using namespace std;int mod;struct MatrixType { int n,m,ai[40][40]; void mem(int n_,int m_) { n=n_,m=m_; for(int i=0;i<=n;i++) { for(int v=0;v<=m;v++) ai[i][v]=0; } } MatrixType operator*(const MatrixType pos)const { MatrixType res; res.mem(n,pos.m); for(int i=0;i<=res.n;i++) { for(int k=0;k<=res.m;k++) { for(int v=0;v<=m;v++) res.ai[i][k]=(res.ai[i][k]+(ai[i][v]*pos.ai[v][k])%mod)%mod; } } return res; } void debug() { puts(""); for(int i=0;i<=n;i++) { for(int v=0;v<=m;v++) printf("%d ",ai[i][v]); putchar(‘\n‘); } puts(""); }};int n,m,ti[1001],Next[1001],last[1001],to[40][40];void poww(MatrixType res,MatrixType pos,int mi){ while(mi) { if(mi&1) res=res*pos; mi=mi>>1,pos=pos*pos; } long long ans=0; for(int i=0;i<m;i++) ans=(ans+res.ai[0][i])%mod; cout<<ans;}int main(){ freopen("data.txt","r",stdin); scanf("%d%d%d",&n,&m,&mod); char ch[30];scanf("%s",ch+1); for(int i=1;i<=m;i++) ti[i]=ch[i]-‘0‘; for(int i=1;i<m;i++) { int v=Next[i]; while(v&&ti[i+1]!=ti[v+1]) v=Next[v]; Next[i+1]=ti[i+1]==ti[v+1]?v+1:0; } for(int i=0;i<m;i++) { for(int v=0;v<=9;v++) { to[i][v]=ti[i+1]==v?i+1:to[Next[i]][v]; } } MatrixType sta,tmp; sta.mem(0,m-1),sta.ai[0][0]=1; tmp.mem(m-1,m-1); for(int i=0;i<m;i++) { for(int v=0;v<=9;v++) { if(to[i][v]!=m) tmp.ai[i][to[i][v]]++; } } poww(sta,tmp,n); return 0;}
AC日记——[HNOI2008]GT考试 bzoj 1009
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。