HDU2243_考研路茫茫――单词情结
给出一些词根,问你有多少种长度为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_考研路茫茫――单词情结的更多相关文章
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)
题目链接:hdu_2243_考研路茫茫——单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...
- hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu2243 考研路茫茫——单词情结【AC自动机】【矩阵快速幂】
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 考研路茫茫――单词情结 HDU - 2243(ac自动机 + 矩阵快速幂)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化
题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memor ...
- HDU 2243 考研路茫茫——单词情结
考研路茫茫——单词情结 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...
- hud2243 考研路茫茫——单词情结
考研路茫茫--单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- HDU-2243 考研路茫茫——单词情结(AC自动机)
题目大意:给n个单词,长度不超过L的单词有多少个包含n个单词中的至少一个单词. 题目分析:用长度不超过L的单词书目减去长度在L之内所有不包含任何一个单词的书目. 代码如下: # include< ...
随机推荐
- 通过group by和having去除重复
$sql="SELECT peisonghao FROM ecs_order_info_ly GROUP BY peisonghao HAVING COUNT(*) >1"; ...
- RabbitMQ、Memcache、Redis(队列、缓存)
RabbitMQ 一.解释 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消 ...
- No.015 3Sum
15. 3Sum Total Accepted: 131800 Total Submissions: 675028 Difficulty: Medium Given an array S of n i ...
- linux+php+apache+mysql(mariadb)故障排除
wordpress 网页文件打不开(client denied by server).白屏(http 500)问题排除顺序 1.查看apache错误日志查照问题报告找到问题 “client denie ...
- java 中小数点的处理
第一种 BigDecimal bg = new BigDecimal(f); double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleVa ...
- (知识分享)软硬件调试九法:第九条规则 如果你不修复一个bug,它将永远存在
1.查证问题确已被修复 如果遵循了“制造失败”这条规则,就知道如何验证你确实修复了问题.无论问题和修复看起来多么明显,你都无法保证修复是有效的,直到做了测试并验证. 2.查证确实你的修复措施解决了问题 ...
- javascript的replace+正则 实现ES6的字符串模版
采用拼接字符串的形式,将 JSON 数据嵌入 HTML 中.开始时代码量较少,暂时还可以接受.但当页面结构复杂起来后,其弱点开始变得无法忍受起来: 书写不连贯.每写一个变量就要断一下,插入一个 + 和 ...
- 线程池的使用ExecutorService
private ExecutorService executorService = Executors.newFixedThreadPool(5); // 引入线程池来管理多线程 private vo ...
- [主页]大牛系列01:Microsoft Research的Johannes Kopf
时间:2015.11.21 版本:初稿 -------------------------------------------------------------------------------- ...
- linux C学习笔记04--内存映射
内存映射代码,打开一个文件与映射到内存中,对内存和文件的修改都会反映到文件中来,反之亦然,先贴代码,以后再完善: /****************************************** ...