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. Robot Framework(七)创建用户关键字

    2.6创建用户关键字 关键字表用于通过将现有关键字组合在一起来创建新的更高级别关键字.这些关键字称为用户关键字,以区别于 测试库中实现的最低级库关键字.创建用户关键字的语法与创建测试用例的语法非常接近 ...

  2. java 网络文件下载(并命中文名)

    public void download(HttpServletRequest request, HttpServletResponse response){ //获取服务器文件 String fil ...

  3. Linux编程之recvmsg和sendmsg函数

    recvmsg 和 sendmsg 函数 #include <sys/types.h> #include <sys/socket.h> ssize_t send(int soc ...

  4. Qt 串口通信 高速发送出错的解决方法总结

    使用网上的qextserialport-1.2类,自行开发多线程串口通信.开发的过程中,出现两个问题:   问题1:我用信号槽跨线程调用串口类MyCom 发送和接收数据,中间运行的时候,会内存错误,Q ...

  5. HearthBuddy CSharpCodeProvider 如何编译cs文件

    源码 源码1 namespace Hearthbuddy.Windows{    // Token: 0x02000041 RID: 65    public class MainWindow : W ...

  6. springboot批量读取参数映射到实体类

    spring读取配置参数可以通过${name}的方式获取,如properties文件中存在如下配置 person.username=xi 则可通过${person.username}获取其对应的值xi ...

  7. LC 718. Maximum Length of Repeated Subarray

    Given two integer arrays A and B, return the maximum length of an subarray that appears in both arra ...

  8. postgres serial创建自增列

    Sequence是数据库中一类特殊的对象,其用于生成唯一数字标识符.一个典型的应用场景就是手动生成一系列主键.Sequence和MySQL中的AUTO_INCREMENT的概念很像. 创建序列Sequ ...

  9. MySQL常用维护命令和操作

    MySQL数据库安装后,除了包括MySQL服务器进程管理外,还提供了大量工具用于管理和维护MySQL服务器的其它工作.下面PHP程序员雷雪松介绍的这些命令都是在MySQL交互界面以外的命令行中执行的. ...

  10. Linux安装sdkman

    项目使用java的开发者一定会为新配环境变量而头大,sdkman很好的解决了系统sdk管理的痛点,仅需简单的几行命令就可以完成sdk的安装,更改默认版本.再也不用担心环境变量的问题. 安装 既然是命令 ...