Foj 2299 Prefix(AC自动机、DP)
Foj 2299 Prefix
题意
给定串s、正整数n,问有多少长度为n的字符串t满足:s[0...i]是t的子串,s[0...i+1]不是。
题解
求有多少长度为n的字符串t满足:s[0...i]是t的子串
这样求出来的数列就是答案的一个前缀和。
具体求法可以对于s[0...i]建一个AC自动机,列出dp式子,状态转移矩阵就很好构造了。
现场主要是没想到每个前缀的方案数要分开求。
代码
#include<cstdio>
#include<cmath>
#include<vector>
#include<iostream>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N = 22, P = 1e9+7;
int n, m;
int f[N];
string s;
int kpow(int a, int b) {
int res = 1;
while(b) {
if(b&1) res = 1ll*res*a%P;
a = 1ll*a*a%P;
b >>= 1;
}
return res;
}
inline int add(int a, int b) {
a+=b;
if(a>=P) a-=P;
return a;
}
inline int sub(int a, int b) {
a-=b;
if(a<0) a+=P;
return a;
}
inline int mul(int a, int b) {
return 1ll*a*b%P;
}
struct Mat {
static const int N = ::N;
int a[N][N], n;
Mat(){} Mat(int _n, int v) { n = _n; rep(i, 0, n) rep(j, 0, n) a[i][j] = i==j ? v : 0; }
Mat operator * (const Mat &c) const {
Mat res(n, 0);
rep(i, 0, n) rep(j, 0, n) rep(k, 0, n) res.a[i][j] = add(res.a[i][j], mul(a[i][k], c.a[k][j]));
return res;
}
Mat operator ^ (int b) const {
Mat res(n, 1), a = *this;
while(b) {
if(b&1) res = res*a;
a = a*a;
b>>=1;
}
return res;
}
};
struct Trie {
static const int N = ::N, M = 26;
int ne[N][M], fail[N], fa[N], rt, L, ed[N];
void init() {
fill_n(ne[fail[0] = N-1], M, 0);
fill_n(ed, L, 0);
L = 0;
rt = newnode();
}
int newnode() {
fill_n(ne[L], M, 0);
return L++;
}
void add(string s) {
int p = rt;
rep(i, 0, sz(s)) {
int c = s[i] - 'A';
if(!ne[p][c]) ne[p][c] = newnode(), fa[L-1] = p;
p = ne[p][c];
}
ed[p] = 1;
}
void build() {
vi v;v.pb(rt);
rep(i, 0, sz(v)) {
int c = v[i];
rep(i, 0, M) ne[c][i] ?
v.pb(ne[c][i]), fail[ne[c][i]] = ne[fail[c]][i] :
ne[c][i] = ne[fail[c]][i];
}
}
Mat getMat() {
Mat mat(L, 0);
rep(i, 0, L) rep(j, 0, M) {
int nex = ed[i] ? i : ne[i][j];
++mat.a[i][nex];
}
return mat;
}
}ac;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int T;
cin >> T;
while(T--) {
cin >> n >> m >> s;
f[0] = kpow(26, n);
rep(i, 1, m+1) {
ac.init();
ac.add(s.substr(0, i));
ac.build();
Mat res = ac.getMat() ^ n;
f[i] = res.a[0][i];
}
rep(i, 0, m) f[i] = sub(f[i], f[i+1]);
rep(i, 0, m+1) cout << f[i] << endl;
}
return 0;
}
Foj 2299 Prefix(AC自动机、DP)的更多相关文章
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2296——Ring(AC自动机+DP)
题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...
- tyvj P1519 博彩游戏(AC自动机+DP滚动数组)
P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...
- bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...
随机推荐
- c++删除容器中的奇数
出自 c++ primer(4th)282页,26题 题意 数组ia[]={0,1,1,2,3,5,8,13,21,55,89};把ia复制到一个list容器中.使用单个迭代器参数版本的erase() ...
- [PY3]——pwd | grp 模块
pwd和grp模块都非常简单粗暴,各自分别下面都只有三个函数,来根据/etc/passwd./etc/group文件获取相关信息 getpwuid(UID):根据UID获取用户信息,返回一个list ...
- 周记6——css实现类似朋友圈九宫格缩略图完美展示
公司有在做一个类似qq空间的开发,发表说说避免不了的要有图片展示. 产品提出的空间缩略图的展示类似*信朋友圈那种效果--图片不变形.能看到中间部分. 这里给出3种解决方案(jsbin地址失效时可复制代 ...
- vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据
在vue项目中组件间相互传值或者后台获取的数据需要供多个组件使用的情况很多的话,有必要考虑引入vuex来管理这些凌乱的状态,今天这边博文用来记录这一整个的过程,后台api接口是使用webpack-se ...
- 在ViewDidLoad中往导航栈推ViewController报错
Unbalanced calls to begin/end appearance transitions for <YZPMainViewController: 0x7fa04b4970f0& ...
- ASP.NET MVC* 采用Unity依赖注入Controller
Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...
- 在方法中new关键字的用处
如果在类A中有M1这个方法需方法 public virtual ovid m1() { console.writeline(“我的世界”); } 那么你在类B中继承的时候可以重写这个方法,也可以不重写 ...
- CentOS虚拟机不能联网状况下yum方式从本地安装软件包
大家都知道yum是linux下一个非常好用的软件安装/卸载软件,它方便操作,而且最厉害的是可以解决令人头疼的包依赖关系.但是若是你的linux不能联网,若想使用yum安装软件,可以依照下面的方法. 1 ...
- js原型及原型链解析
js原型.原型链 这几天闲了看了下js的原型,以下内容为个人理解,如有错误,尽请指正. 首先,明确一点:js中的对象分为普通对象和函数对象,一般我们自定义的可以被new的函数称作函数对象,另外js内置 ...
- java读取项目或包下面的属性文件方法
1.使用java.util.Properties类的load()方法 //文件在项目下.不是在包下!! InputStream in = new BufferedInputStream(newFile ...