给出一些词根,问你有多少种长度为L的串包含至少一个词根。

去年就在敲这个题了,今年才敲出来,还是内牛满面之中。。。

要求包含至少一个的情况,需要求出所有的情况,减去一个都没有的情况就可以了。

对于给出的词根,上自动机。然后我们根据tire图可以得出关系状态转移的矩阵。

显然就是矩阵求和了,通过二分幂解决即可。这些地方都有一些技巧可言的。

一开始没有考虑压缩fail指针,考虑了非法的情况,真是wa出翔了。

召唤代码君:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
typedef unsigned long long ll;
using namespace std; ll n,L;
ll next[][],fail[],tag[],N; struct Mat{
ll a[][];
Mat() { memset(a,,sizeof a); }
Mat operator + (Mat M) const {
Mat tmp;
for (ll i=; i<=n; i++)
for (ll j=; j<=n; j++) tmp.a[i][j]=a[i][j]+M.a[i][j];
return tmp;
}
Mat operator * (Mat M) const {
Mat tmp;
for (ll i=; i<=n; i++)
for (ll j=; j<=n; j++)
for (ll k=; k<=n; k++)
tmp.a[i][j]+=a[i][k]*M.a[k][j];
return tmp;
}
Mat power(ll x)
{
Mat tmp1,tmp2;
for (ll i=; i<=n; i++){
tmp1.a[i][i]=;
for (ll j=; j<=n; j++){
tmp2.a[i][j]=a[i][j];
}
}
while (x){
if (x&) tmp1=tmp1*tmp2;
x>>=,tmp2=tmp2*tmp2;
}
return tmp1;
}
void output(){
for (ll i=; i<=n; i++){
for (ll j=; j<=n; j++) cout<<a[i][j]<<' ';
cout<<endl;
}
}
}; ll add()
{
fail[++N]=,tag[N]=;
for (ll i=; i<; i++) next[N][i]=;
return N;
} void insert(char s[])
{
ll cur=,k;
for (ll i=; s[i]; i++){
k=s[i]-'a';
if (!next[cur][k]) next[cur][k]=add();
cur=next[cur][k];
}
tag[cur]=;
} void AC_build()
{
queue<int> Q;
Q.push();
while (!Q.empty()){
ll cur=Q.front(),child,k;
Q.pop();
for (ll i=; i<; i++){
child=next[cur][i];
if (child){
if (!cur) fail[child]=;
else{
for (k=fail[cur]; k && !next[k][i]; k=fail[k]) ;
fail[child]=next[k][i];
}
Q.push(child);
}
else next[cur][i]=next[fail[cur]][i];
}
}
} ll power(ll x,ll y)
{
ll tot=;
while (y){
if (y&) tot=tot*x;
y>>=,x=x*x;
}
return tot;
} int main()
{
char s[];
while (cin>>n>>L){
N=;
fail[]=tag[]=;
for (ll i=; i<; i++) next[][i]=;
for (ll i=; i<n; i++)
{
scanf("%s",s);
insert(s);
}
AC_build();
for (ll i=; i<=N; i++)
if (tag[fail[i]]) tag[i]=;
n=N;
Mat cur,E,ans;
for (ll i=; i<=n; i++)
for (ll j=; j<; j++){
if (!tag[i] && !tag[next[i][j]]) cur.a[i][next[i][j]]++;
} for (ll i=; i<=n; i++) E.a[i][i]=;
Mat tmp=E;
ll num=,here=;
while (L>){
if (L&) {
ans=ans+tmp*cur.power(L);
num+=here*power(,L);
}
L>>=;
here=here*power(,L)+here;
tmp=tmp*(cur.power(L)+E);
}
for(ll i=; i<=n; i++) num-=ans.a[][i];
cout<<num<<endl;
}
return ;
}

HDU2243_考研路茫茫――单词情结的更多相关文章

  1. HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)

    题目链接:hdu_2243_考研路茫茫——单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...

  3. hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. hdu2243 考研路茫茫——单词情结【AC自动机】【矩阵快速幂】

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. 考研路茫茫――单词情结 HDU - 2243(ac自动机 + 矩阵快速幂)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化

    题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memor ...

  7. HDU 2243 考研路茫茫——单词情结

    考研路茫茫——单词情结 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...

  8. hud2243 考研路茫茫——单词情结

    考研路茫茫--单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

  9. HDU-2243 考研路茫茫——单词情结(AC自动机)

    题目大意:给n个单词,长度不超过L的单词有多少个包含n个单词中的至少一个单词. 题目分析:用长度不超过L的单词书目减去长度在L之内所有不包含任何一个单词的书目. 代码如下: # include< ...

随机推荐

  1. linux下安装jdk的几种方式

    1.rpm方式安装: rpm -qa | grep jdk 查看是否安装了jdk,或者用java -version查看java版本 rpm -e --nodeps java-1.7.0-openjdk ...

  2. sql创建表格 转载

    http://blog.csdn.net/wuxiaokaixinguo/article/details/8293048 检查数据库中是否存在某个表,不存在则生成该表方法一:IF NOT EXISTS ...

  3. SpringBoot之springfox(Swagger) (ApiDoc接口文档)

    Springfox的前身是swagger-springmvc,是一个开源的API doc框架,可以将我们的Controller的方法以文档的形式展现,基于Swagger. 官网地址:http://sp ...

  4. css绝对定位问题

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. nbu恢复 oracle10g rac asm 到单实例asm(恢复某个表空间)

    一 检验条件 二 准备工作 1 创建相关目录 mkdir -p /oracle/admin/orcl/adumpmkdir -p /oracle/admin/orcl/bdumpmkdir -p /o ...

  6. 19. Palindrome Partitioning && Palindrome Partitioning II (回文分割)

    Palindrome Partitioning Given a string s, partition s such that every substring of the partition is ...

  7. history 查看历史操作记录在shell脚本执行中无法显示问题

    今天使用shell脚本想查看历史操作命令的记录于是写了一个再简单不过的脚本,可是以chmod +x 权限执行./test.sh发现执行后没有任何反应.于是查找原因:将脚本文件中的#!/bin/bash ...

  8. AX2012 审批流流转到已停用的域账号导致审批流停止

    AX 2012 中当审批流流转到某个节点时,如果在该节点的审批人的域账号被停用,审批流将会停止,会报如图的错误: 要解决这个问题,得修改标准功能,需要修改SysWorkflow和SysWorkflow ...

  9. 使用PHP导入和导出CSV文件

    我们先准备mysql数据表,假设项目中有一张记录学生信息的表student,并有id,name,sex,age分别记录学生的姓名.性别.年龄等信息. CREATE TABLE `student` ( ...

  10. 【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

    简单介绍:Enumerable 和 Queryable 他们都是静态类,位于命名控件 System.Linq下,分别为IEnumerable<T>和IQueryable<T>提 ...