【[TJOI2018]碱基序列】
为什么没人用\(SAM\)啊
我们先把原来的模式串建一遍\(SAM\),之后我们就可以求出\(SAM\)上每一个节点的\(|endpos|\)就可以知道每一个子串出现的次数了,也就是在模式串上的匹配数了
之后我们设\(dp[i][j]\)表示前\(i\)个里组合出的子串在\(SAM\)上匹配到了\(j\)位置的方案数是多少,转移的时候就枚举每一个子串以及\(SAM\)上的每一个节点之后跑匹配就好了
最后的答案就是
\]
之后第一维甚至可以直接滚动掉
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 100005
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int mod=1e9+7;
struct E{int v,nxt;}e[maxn<<1];
int fa[maxn<<1],son[maxn<<1][26],len[maxn<<1],head[maxn<<1],sz[maxn<<1];
char S[maxn];
int dp[2][maxn<<1];
int n,m,num,cnt=1,lst=1,ans,o;
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
void dfs(int x) {for(re int i=head[x];i;i=e[i].nxt) dfs(e[i].v),sz[x]+=sz[e[i].v];}
inline void ins(int c)
{
	int f=lst,p=++cnt; lst=p;
	len[p]=len[f]+1,sz[p]=1;
	while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
	if(!f) {fa[p]=1;return;}
	int x=son[f][c];
	if(len[f]+1==len[x]) {fa[p]=x;return;}
	int y=++cnt; len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
	for(re int i=0;i<26;i++) son[y][i]=son[x][i];
	while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
}
inline int find(int now) {for(re int i=1;i<=n;i++) {now=son[now][S[i]-'A'];if(!now) break;}return now;}
int main()
{
	scanf("%d",&m);scanf("%s",S+1);n=strlen(S+1);
	for(re int i=1;i<=n;i++) ins(S[i]-'A');
	for(re int i=2;i<=cnt;i++) add(fa[i],i);dfs(1);
	dp[0][1]=1; o=0;
	for(re int i=1;i<=m;i++)
	{
		int T; o^=1; scanf("%d",&T);
		for(re int j=1;j<=cnt;j++) dp[o][j]=0;
		for(re int j=1;j<=T;j++)
		{
			scanf("%s",S+1);n=strlen(S+1);
			for(re int k=1;k<=cnt;k++)
			if(dp[o^1][k]) {int v=find(k);if(v) dp[o][v]=(dp[o][v]+dp[o^1][k])%mod;}
		}
	}
	for(re int i=2;i<=cnt;i++) ans=(ans+(LL)dp[o][i]*(LL)sz[i]%mod)%mod;
	printf("%d\n",ans);
	return 0;
}
												
											【[TJOI2018]碱基序列】的更多相关文章
- 洛谷P4591 [TJOI2018]碱基序列(hash dp)
		
题意 题目链接 Sol \(f[i][j]\)表示匹配到第\(i\)个串,当前在主串的第\(j\)个位置 转移的时候判断一下是否可行就行了.随便一个能搞字符串匹配的算法都能过 复杂度\(O(|S| K ...
 - [TJOI2018]碱基序列
		
嘟嘟嘟 现在看到字符串就想到SAM,所以很担心kmp啥的会不会忘了-- 这题感觉挺暴力的:首先当然要把\(s\)建成SAM,然后令\(dp[i][j]\)表示到第\(i\)组时,SAM上节点\(j\) ...
 - BZOJ5337 [TJOI2018] 碱基序列 【哈希】【动态规划】
		
题目分析: 这道题的难点在于要取模,而题面没有写. 容易想到一个O(1E7)的dp.KMP或者哈希得到相关位置然后对于相关位置判断上一个位置有多少种情况. 代码: #include<bits/s ...
 - 洛谷P4591 [TJOI2018]碱基序列 【KMP + dp】
		
题目链接 洛谷P4591 题解 设\(f[i][j]\)表示前\(i\)个串匹配到位置\(j\)的方案数,匹配一下第\(i\)个串进行转移即可 本来写了\(hash\),发现没过,又写了一个\(KMP ...
 - 「学习笔记」字符串基础:Hash,KMP与Trie
		
「学习笔记」字符串基础:Hash,KMP与Trie 点击查看目录 目录 「学习笔记」字符串基础:Hash,KMP与Trie Hash 算法 代码 KMP 算法 前置知识:\(\text{Border} ...
 - bzoj 5338: [TJOI2018]xor (树链剖分+可持久化01Trie)
		
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5338 题面: 5338: [TJOI2018]xor Time Limit: 30 Sec ...
 - [模板] dp套dp && bzoj5336: [TJOI2018]party
		
Description Problem 5336. -- [TJOI2018]party Solution 神奇的dp套dp... 考虑lcs的转移方程: \[ lcs[i][j]=\begin{ca ...
 - 洛谷P4590 [TJOI2018]游园会(状压dp LCS)
		
题意 题目链接 Sol 这个题可能是TJOI2018唯一的非模板题了吧.. 考虑LCS的转移方程, \[f[i][j] = max(f[i - 1][j], f[i][j - 1], f[i - 1] ...
 - 【BZOJ5339】[TJOI2018]教科书般的亵渎(斯特林数)
		
[BZOJ5339][TJOI2018]教科书般的亵渎(斯特林数) 题面 BZOJ 洛谷 题解 显然交亵渎的次数是\(m+1\). 那么这题的本质就是让你求\(\sum_{i=1}^n i^{m+1} ...
 
随机推荐
- Callable,Runnable的区别及用法
			
编写多线程程序一般有三种方法,Thread,Runnable,Callable. Runnable和Callable的区别是: (1)Callable规定的方法是call(),Runnable规定的方 ...
 - stream2
			
import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.function.B ...
 - tcp中  fast_open  学习    nginx 13年的版本开始支持该功能
			
https://www.cnblogs.com/lanjianhappy/p/9868622.html 三次握手的过程中,当用户首次访问server时,发送syn包,server根据用户IP生成coo ...
 - Java-IO中的节点流和处理流
			
理解好Java-IO中的节点流和处理流是理解Java输入.输出的关键基础,因此,了解节点流和处理流相关的知识点尤为重要. 1.定义 (1)节点流:可以从或向一个特定的地方(节点)读写数据.如FileR ...
 - 虚拟机安装MySQL报** is needed by **错误
			
执行命令: [root@node1 local]# rpm -ivh mysql-community-server-8.0.12-1.el7.x86_64.rpm 安装MySQL遇到以下问题: err ...
 - 剑指offer中经典的算法题之从头到尾打印链表
			
话不多说上代码: 我自己的算法是: /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int ...
 - Hidden Markov Models笔记
			
Andrew Ng CS229 讲义: https://pan.baidu.com/s/12zMYBY1NLzkluHNeMNO6MQ HMM模型常用于NLP.语音等领域. 马尔科夫模型(Markov ...
 - PlayMaker Debug Int/Float/Vector3...
			
1.在一个游戏对象上建一个PlayMakerFSM,在状态机里新建几个不同类型的变量: 2.再新加几个Action: 3.运行,结果如下:
 - [转]理解js中的原型链,prototype与__proto__的关系
			
本文转自:http://rockyuse.iteye.com/blog/1426510 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script typ ...
 - Murano Weekly Meeting 2016.07.12
			
Meeting time: 2016.July.12 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summary: 1. ...