【题目大意】

给出单词总数和固定的文章长度M,求出至少包含其中一个单词的可能文章数量。

【思路】

对于至少包含一个的类型,我们可以考虑补集。也就是等于[总的文章可能性总数-不包含任意一个单词的文章总数]有两个注意点:

1.Trie图+DP。Trie图和AC自动机的区别在于,当孩子i为NULL时,则让孩子指针等于fail指针的孩子i,这样就可以继续匹配下去了。因此寻找fail指针的时候,可以不用循环而用判断语句即可。

2.danger表示当前位置包含了单词,所以DP的时候舍去。如果你指向的fail指针是danger的,也就是你的后缀是danger的,那么当前的也是danger的。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=+;
const int MAXM=+;
const int MOD=;
const int NUMA=;
int n,m,cnt=;
struct ACauto
{
int id;
int danger;
ACauto* next[NUMA];
ACauto* fail;
ACauto()
{
danger=;
id=++cnt;
for (int i=;i<NUMA;i++) next[i]=NULL;
fail=NULL;
}
};
ACauto* node[MAXN*MAXM];
int f[MAXN][MAXM*MAXN]; void insert(ACauto* root,char* str)
{
int len=strlen(str);
ACauto* tmp=root; for (int i=;i<len;i++)
{
int index=str[i]-'A';
if (tmp->next[index]==NULL)
{
tmp->next[index]=new ACauto;
node[cnt]=tmp->next[index];
}
tmp=tmp->next[index];
}
tmp->danger=;
} void build(ACauto* root)
{
queue<ACauto*> que;
que.push(root);
while (!que.empty())
{
ACauto* head=que.front();que.pop();
for (int i=;i<NUMA;i++)
{
if (head->next[i]==NULL)
{
if (head==root) head->next[i]=root;
else head->next[i]=head->fail->next[i];
}
else
{
if (head==root) head->next[i]->fail=root;
else
{
head->next[i]->fail=head->fail->next[i];
if (head->next[i]->fail->danger) head->next[i]->danger=;/*注意!*/
}
que.push(head->next[i]);
}
}
}
} void dp(ACauto* root)
{
memset(f,,sizeof(f));
f[][]=;
for (int i=;i<=m-;i++)
for (int j=;j<=cnt;j++)
{
if (!node[j]->danger && f[i][j])
{
for (int k=;k<NUMA;k++)//枚举下一个字母
if (!node[j]->next[k]->danger)
f[i+][node[j]->next[k]->id]=(f[i][j]+f[i+][node[j]->next[k]->id])%MOD;
}
}
} void findres()
{
int ans1=,ans2=;
for (int i=;i<=cnt;i++)
if (!node[i]->danger) ans1=(ans1+f[m][i])%MOD;
for (int i=;i<=m;i++) ans2=(ans2*NUMA)%MOD;
cout<<(ans2-ans1+MOD)%MOD<<endl;
} int main()
{
char str[MAXN];
ACauto* root=new ACauto;
node[]=root;
scanf("%d%d",&n,&m);
for (int i=;i<n;i++)
{
scanf("%s",str);
insert(root,str);
} build(root);
dp(root);
findres();
return ;
}

【Trie图+DP】BZOJ1030[JSOI2007]-文本生成器的更多相关文章

  1. BZOJ1030 JSOI2007 文本生成器 【AC自动机】【DP】*

    BZOJ1030 JSOI2007 文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为"文本生成器"的电脑软件:该软件的使用者是一些低幼人群,他们现 ...

  2. [Bzoj1030][JSOI2007]文本生成器(AC自动机)(dp)

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5254  Solved: 2172[Submit][Stat ...

  3. bzoj1030 [JSOI2007]文本生成器

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2654  Solved: 1100[Submit][Stat ...

  4. BZOJ1030: [JSOI2007]文本生成器(Trie图+dp)

    Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  5. [BZOJ1030] [JSOI2007] 文本生成器 (AC自动机 & dp)

    Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  6. BZOJ1030[JSOI2007]文本生成器——AC自动机+DP

    题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...

  7. [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)

    题目传送门 题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  8. BZOJ1030: [JSOI2007]文本生成器(AC自动机)

    Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5984  Solved: 2523[Submit][Status][Discuss] Descripti ...

  9. BZOJ1030 [JSOI2007]文本生成器[DP+AC自动机]

    我学到现在才是初三学弟的水平..哭 这里相当于求长度为$m$的,字符集$\{A...Z\}$的且不包含任一模式串的文本串个数.这是一个典型的AC自动机匹配计数问题. 设$f_{i,j}$表示在AC自动 ...

随机推荐

  1. js获取屏幕高度宽度

    获取各种屏幕的宽度和高度Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽 ...

  2. js_读【javascript面向对象编程指南】笔记

    写在前面: 工欲善其事,必先利其器.编程的器,是前人总结的经验,常言道站在巨人的肩膀上开发,往往比自己另辟蹊径容易的多.经验藏于书,故有书中自有颜如玉,书中自有黄金屋,我也一度认为读书要花费很多时间, ...

  3. C++学习之路(四):线程安全的单例模式

    (一)简单介绍 单例模式分为两种类型:懒汉模式和饿汉模式. 懒汉模式:在实际类对象被调用时才会产生一个新的类实例,并在之后返回这个实例.多线程环境下,多线程可能会同时调用接口函数创建新的实例,为了防止 ...

  4. python 判断文件的创建时间和当前时间的比较

    import os import time import datetime filePath=r"C:\pyweibo\cookies5673210223" ctime=os.pa ...

  5. MyBatis 模糊查询 防止Sql注入

    #{xxx},使用的是PreparedStatement,会有类型转换,所以比较安全: ${xxx},使用字符串拼接,可以SQL注入: like查询不小心会有漏洞,正确写法如下:   Mysql:   ...

  6. Oracle中的case when then else end 应用

    Case when 的用法,简单Case函数 简单CASE表达式,使用表达式确定返回值. 语法: CASE search_expression WHEN expression1 THEN result ...

  7. 微信小程序-ios系统-下拉上拉出现白色,如何处理呢?

    这几天做小程序,有些页面都是全屏的背景,在安卓上背景是固定的,而在ios上上拉下拉出现白色,测试说体验不太好,一开始我以为是下拉上拉刷新造成的,关闭了依然是这样.为了体验好点,可以按一下解决: 方式一 ...

  8. hdu 多校第一场

    1001 思路:打表可以发现只有3|n 和 4|n 的情况有解,判一下就好啦. #include<bits/stdc++.h> #define LL long long #define f ...

  9. SpringMVC组件配置

    web.xml . springmvc-servlet.xml 配置SpringMVC四大组件. web.xml 配置前端控制器:前端控制器就是个servlet <!-- 配置前端控制器 --& ...

  10. Power BI连接至Mogo Altas Connector For BI

    我需要使用Power BI连接至Connector For BI ,现在Connect For BI存放在Mongo Atlas中,详细的来自于官方文档,https://docs.atlas.mong ...