Separate String

时间限制: 1 Sec  内存限制: 128 MB
提交: 50  解决: 16

题目描述

You are given a string t and a set S of N different strings. You need to separate t such that each part is included in S.

For example, the following 4 separation methods satisfy the condition when t=abab and S={a,ab,b}.

a,b,a,b
a,b,ab
ab,a,b
ab,ab
Your task is to count the number of ways to separate t. Because the result can be large, you should output the remainder divided by 1,000,000,007.

输入

The input consists of a single test case formatted as follows.

N
s1
:
sN
t
The first line consists of an integer N (1≤N≤100,000) which is the number of the elements of S. The following N lines consist of N distinct strings separated by line breaks. The i-th string si represents the i-th element of S. si consists of lowercase letters and the length is between 1 and 100,000, inclusive. The summation of length of si (1≤i≤N) is at most 200,000. The next line consists of a string t which consists of lowercase letters and represents the string to be separated and the length is between 1 and 100,000, inclusive.

输出

Calculate the number of ways to separate t and print the remainder divided by 1,000,000,007.

样例输入

3
a
b
ab
abab

样例输出

4

题解:在kuangbin的板子当中增加ln(以此为结尾的字符串的长度),true_nex(也可以叫做true_fail,用于表示真正有效的fail值,即存在以此为结尾的字符串)数组;
true_nex数组层层计算即可,因为上层的true_nex肯定已被正确计算。然后在query函数里面跑一个简单的DP即可。 AC代码:
 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+;
const int maxn=1e6+;
ll dp[maxn];
struct Trie
{
int nxt[][],fail[],endd[],ln[],true_nex[];
int root,L;
int newnode(){
for(int i=;i<;i++){
nxt[L][i]=-;
}
true_nex[L]=;
ln[L]=;
endd[L++]=;
return L-;
}
void init(){
L=;
root=newnode();
}
void insert(char buf[])
{
int len=strlen(buf);
int now=root;
for(int i=;i<len;i++){
if(nxt[now][buf[i]-'a']==-){
nxt[now][buf[i]-'a']=newnode();
ln[nxt[now][buf[i]-'a']]=ln[now]+;
}
now=nxt[now][buf[i]-'a'];
}
endd[now]++;
}
void build()
{
queue<int> Q;
fail[root]=root;true_nex[root]=root;
for(int i=;i<;i++){
if(nxt[root][i]==-){
nxt[root][i]=root;
}
else{
fail[nxt[root][i]]=root;
true_nex[nxt[root][i]]=root;/**/
Q.push(nxt[root][i]);
}
}
while(!Q.empty())
{
int now=Q.front();
Q.pop();
for(int i=;i<;i++)
{
if(nxt[now][i]==-){
nxt[now][i]=nxt[fail[now]][i];
}
else{
fail[nxt[now][i]]=nxt[fail[now]][i];
if(endd[nxt[fail[now]][i]]>) true_nex[nxt[now][i]]=nxt[fail[now]][i];/**/
else true_nex[nxt[now][i]]=true_nex[nxt[fail[now]][i]];/**/
Q.push(nxt[now][i]);
}
}
}
}
ll query(char buf[])
{
int len=strlen(buf);
int now=root;
int res=;
dp[]=;
for(int i=;i<len;i++)
{
now=nxt[now][buf[i]-'a'];
int temp=now;
while(temp!=root)
{
dp[i+]=(dp[i+]+dp[i+-ln[temp]]*endd[temp])%mod;
temp=true_nex[temp];
}
}
return dp[len];
}
}ac;
int n;
char buf[maxn];
int main()
{
int t=;
for(;t;t--)
{
scanf("%d",&n);
ac.init();
while(n--)
{
scanf("%s",buf);
ac.insert(buf);
}
ac.build();
scanf("%s",buf);
printf("%lld\n",ac.query(buf));
}
return ;
}
 

Separate String的更多相关文章

  1. 10 Things Every Java Programmer Should Know about String

    String in Java is very special class and most frequently used class as well. There are lot many thin ...

  2. 4 .Swift函数|闭包

    在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...

  3. URL Parsing

    [URL Parsing] urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True) Parse a URL into six ...

  4. Swift函数|闭包

    在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...

  5. .NET 并行编程——任务并行

    本文内容 并行编程 任务并行 隐式创建和运行任务 显式创建和运行任务 任务 ID 任务创建选项 创建任务延续 创建分离的子任务 创建子任务 等待任务完成 组合任务 任务中的异常处理 取消任务 Task ...

  6. bsdasm

    bsdasm 来源 http://www.int80h.org/bsdasm/ Preface by G. Adam StanislavWhiz Kid Technomagic Assembly la ...

  7. php数组与字符串转换

    1.将字符串转换成数组的几个函数: (1)explode(separate,string) 示例:$str = "Hello world It's a beautiful day" ...

  8. Base Conversion In PHP and javascript

    http://www.exploringbinary.com/base-conversion-in-php-using-built-in-functions/ http://www.binarycon ...

  9. C string.h 常用函数

    参考:http://womendu.iteye.com/blog/1218155 http://blog.csdn.net/zccst/article/details/4294565 还有一些,忘记了 ...

随机推荐

  1. 关于hbase的数据迁移

    场景: 一套自己编译的Hbase集群 A 一套自己通过cloudera平台搭建的Hbase集群 B 注意:( 我的两套集群是同一个网段的) 方式1:通过快照方式进行数据迁移(不需要提前建表) 1):首 ...

  2. HTML5 烟花系统

    需求:在一个虚拟烟花球中,在不同的部位填充不同颜色.质地的烟花火药:观看试放效果.最好能结合点物理学定律(以便展现火药粉被爆炸扩散到一定程度再爆炸的效果) 这是这学期的一个作业,感觉挺无聊的,纯粹是老 ...

  3. python并发——信号量

    信号量通常用于保护数量有限的资源,例如数据库服务器.在资源数量固定的任何情况下,都应该使用有界信号量.在生成任何工作线程前,应该在主线程中初始化信号量. 工作线程生成后,当需要连接服务器时,这些线程将 ...

  4. 预处理、const、static与sizeof-为什么要引入内联函数

    1:引入内联函数的主要目的是,用它替代C语言中表达形式的宏定义来解决程序中函数调用的效率问题.在C语言里可以使用如下的宏定义: #define ExpressionName(Var1,Var2) (V ...

  5. springboot使用RestTemplate以post方式发送json字符串参数(以向钉钉机器人发送消息为例)

    使用springboot之前,我们发送http消息是这么实现的 我们用了一个过时的类,虽然感觉有些不爽,但是出于一些原因,一直也没有做处理,最近公司项目框架改为了springboot,springbo ...

  6. koa 项目实战(八)生成token

    1.安装模块 npm install jsonwebtoken --save 2.引用 const jwt = require('jsonwebtoken'); ... // 返回token cons ...

  7. 微信小程序之状态管理A

    其实这个标题 不是很对 主要是最近小程序项目中 有这么一个状态 所有商品都共用一个商品详情页面  大概就是这样子  为了公司 保险起见,一些展示的内容已经处理 但是无伤大雅 就是这么两个按钮 左侧粉色 ...

  8. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-2.微信扫一扫功能开发前期准备

    笔记 2.微信扫一扫功能开发前期准备         简介:讲解微信扫一扫功能相关开发流程和资料准备              1.微信开放平台介绍(申请里面的网站应用需要企业资料)          ...

  9. Cetos 7 命令行登陆与图形界面登陆相互切换

    环境:vmware 虚拟机: 系统:Cetos 7 64位: 引言:有一台虚拟机,安装的时候选择的是最小化安装,是没有图形界面的,后来有需求,需要有个图形界面,所以就准备把这个升级下,下面是操作步骤: ...

  10. React Native的生命周期

    就像 iOS开发中 一样,React Native(RN) 中的组件也有生命周期(Lifecycle).所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命周期,是合理开发的关键.RN ...