L 语言:很好的一道状压 dp 题。

思路

看到这题,首先可以想到一个很暴力的 dp,设 \(dp_i\) 表示考虑到第 \(i\) 位能否被理解,暴力匹配字符串转移即可。

第一个优化也很显然,暴力匹配字符串换成 AC 自动机即可。

但是时间复杂度变成了 \(O(m|T||S|)\) 的,显然会被卡。

状压与位运算优化

观察到 \(|S|=20\),所以我们最多只能往前转移 \(20\) 位,这就启发我们用一个 int 存下 dp 状态,用位运算优化转移。这个技巧通常用于可行性 dp 也就是只有 \(0/1\) 状态的 dp 里。

同时我们也需要在 fail 树上预处理出某个节点能接受转移的长度,然后每次和当前 dp 状态与运算一下就好了。

时间复杂度 \(O(m|T|)\)。

坑点

dp 状态取模的时候要取 \(2_i\),如果任取一个数那么会导致 dp 完全乱掉。反例也很好举,例如 \(114514 \bmod 2^{10} \ne 114514 \bmod 1000\)。

同时字典树 insert 要用 insert(s) 而不是 insert(s+1),我已经错了两遍以上了。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
const int mod=2097152;
int n,m,ch[1005][30],idx=0,tot[1005],ne[1005],dp=0,ans=0;
vector<int>g[1005];
char s[1005],t[4000005];
void insert(char *s)
{
int p=0; for(int i=1;s[i];i++)
{
int c=s[i]-'a';
if(ch[p][c]==0)ch[p][c]=++idx;
p=ch[p][c];
}
tot[p]=(tot[p]|(1<<(strlen(s+1))));
}
void build()
{
queue<int>q;
for(int i=0;i<26;i++)
{
if(ch[0][i])q.push(ch[0][i]);
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<26;i++)
{
int v=ch[u][i];
if(v)ne[v]=ch[ne[u]][i],q.push(v);
else ch[u][i]=ch[ne[u]][i];
}
}
}
void dfs1(int u)
{
for(auto v:g[u])
{
tot[v]=(tot[v]|tot[u]);
dfs1(v);
}
}
void init()
{
for(int i=1;i<=idx;i++)g[ne[i]].push_back(i);
dfs1(0);
}
void solve()
{
cin>>t+1;
int len=strlen(t+1),p=0;
dp=1;
ans=0;
for(int i=1;i<=len;i++)
{
int c=t[i]-'a';
p=ch[p][c];
int now=tot[p];
dp<<=1;
dp%=mod;
int hv=(dp&now);
if(hv)dp|=1,ans=i;
if(dp==0)break;
}
cout<<ans<<'\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>s+1;
insert(s);
}
build();
init();
while(m--)solve();
return 0;
}

Luogu P2292 HNOI2004 L 语言 题解 [ 紫 ] [ AC 自动机 ] [ 状压 dp ]的更多相关文章

  1. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  2. Luogu P2292 [HNOI2004]L语言(Trie+dp)

    P2292 [HNOI2004]L语言 题面 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章 \(T\) 是由若干小写字母构成. ...

  3. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  4. BZOJ1559 [JSOI2009]密码 【AC自动机 + 状压dp】

    题目链接 BZOJ1559 题解 考虑到这是一个包含子串的问题,而且子串非常少,我们考虑\(AC\)自动机上的状压\(dp\) 设\(f[i][j][s]\)表示长度为\(i\)的串,匹配到了\(AC ...

  5. zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)

    Time Limit: 10 Seconds      Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...

  6. hdu 4057--Rescue the Rabbit(AC自动机+状压DP)

    题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...

  7. hdu2825 Wireless Password(AC自动机+状压dp)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  8. 【Luogu】P2292 [HNOI2004]L语言 题解

    前置芝士:\(Trie\)字典树 这道题,说是AC自动机,实际上一个\(Trie+\)队列轻松搞定. 首先,我们对所有单词建一棵\(Trie\). 然后,定义一个空队列\(Q\),初始时把\(-1\) ...

  9. Luogu P2292 [HNOI2004]L语言

    题目链接 \(Click\) \(Here\) 好久没写\(DP\)了真是水平下降不少,一眼把这个题搞成贪心了,然后一发交上只有\(37\)分\(QwQ\) 这个题好像还可以\(AC\)自动机胡搞?不 ...

  10. HDU 2825 Wireless Password(AC自动机 + 状压DP)题解

    题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...

随机推荐

  1. Codeforces Round 797 (Div

    Codeforces Round 797 (Div. 3) Price Maximization 给定\(n\)个商品(n为偶数),每个商品的重量为\(a_i\),你需要将其两两打包,打包的成本为\( ...

  2. Mybatis【10】-- Mybatis属性名和查询字段名不同怎么做?

    很多时候我们有这样的需求,数据库的字段名与实体类的属性名不一致,这个时候我们需要怎么做呢?有两种解决方案,第一种:直接在查询的时候使用别名,将别名设置成与实体类的属性名一致.第二种:使用resultT ...

  3. AtCoder Beginner Contest 378

    Contest Link 还得加练. A & B & C & D 不具备任何思维含量. Submission A Submission B Submission C Submi ...

  4. H5 新增表单

    1.提示占位 placeholder <input type="text" name="userName" placeholder="请输入用户 ...

  5. 正也科技案例 | 药企使用S2P深入营销管理数据化建设

    为了获取更*的市场空间,医药健康行业正迎来一波前所未有的产业升级.尽管不少企业取得了许多成绩,但仍面临诸多挑战. 浙江某知名医药公司,在泌尿系统.心脑血管系统及眼科用药领域均拥有强势品牌.其产品更是荣 ...

  6. DDPM论文解读

    DDPM(Denoising Diffusion Probabilistic Models) 论文研究背景 扩散概率模型(Denoising Diffusion Probabilistic Model ...

  7. HarmonyOS Next 入门实战 - 文字转拼音,文字转语音

    文字转拼音 安装 pinyin4js 三方库 ohpm install @ohos/pinyin4js pinyin4js 提供了以下接口: ● 文字转拼音(带声调和不带声调) ● 文字转拼音首字母 ...

  8. 1.猿人学web爬虫攻防第一题 js混淆源码乱码

    题目链接:http://match.yuanrenxue.com/match/1 1.首先我们打开F12开发者工具,点击..... 我们可以看到在请求中有m的加密参数! 2.根据题目js混淆,我们寻找 ...

  9. 【Linux】课堂练习作业

    # 作业Day01-关机练习作业 查询在线用户 who -H 查询服务状态 systemctl status sshd 停止服务 systemctl stop sshd 停止后再次检查服务状态 方法一 ...

  10. 【MyBatis】学习笔记05:获取参数值的两种方式

    [Mybatis]学习笔记01:连接数据库,实现增删改 [Mybatis]学习笔记02:实现简单的查 [MyBatis]学习笔记03:配置文件进一步解读(非常重要) [MyBatis]学习笔记04:配 ...