P2292 [HNOI2004]L语言
传送门
思路:
毒瘤的字典树!
▲主要分有两个步骤:
① 日常的建树。
② 暴力地求解。
▲日常建树:过于基础,跳过。
▲重点在于如何暴力地求解而不被卡掉(DP?不存在的)
可以利用区间动规的思想,枚举文章的左右端点,判断中间区间的文章是否可以被理解。
文章的长度几乎为 INF ,直接 N2 枚举 1~INF 显然是不可能的。
而看到字典里的单词长度(模式串)长度只有 10 以下,这为暴力枚举提供了一条出路。
先看一段暴力求解的代码:
for(LL j=;j<len;j++)//很暴力的枚举文章的右端点
for(LL k=max(j-lenth_max,-INF);k<=j;k++)//枚举文章的区间左端点,(有k=max(j-lenth_max,-INF)每次最多只有枚举10个单位长度)。
if((k==-INF||f[k])&&(find(k+,j)))
{
f[j]=true;ans=j+;break;
}//注-INF = -1
find( i , j ) 用于查找 i~j 的文章中,是否能够成功匹配单词。
设一个 f[ j ] 表示整篇文章中,k ~ j 的文章区间能否被理解,同时要求之前文章的 f[ k ] 也要能够被理解才能更新 ans 。( 因为要求求解能够被理解的文章最长前缀 ,不能断开 )。
为了能够更加优化暴力,lenth_max 记录最长的单词长度。
有个小细节:在匹配成功一段区间后的 break ,跳出的只是枚举左端点的循环,而外层的枚举右端点的循环仍然继续。
标程:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define maxn 1000002
#define INF 1
typedef long long LL;
LL n,m,len,lenth_max,ans,ch[maxn>>][],cnt;
char s[maxn];
bool f[maxn],bo[maxn>>];
inline LL read()
{
LL kr=,xs=;
char ls;
ls=getchar();
while(!isdigit(ls))
{
if(!(ls^))
kr=-;
ls=getchar();
}
while(isdigit(ls))
{
xs=(xs<<)+(xs<<)+(ls^);
ls=getchar();
}
return xs*kr;
}
inline void insert(char *s)
{
LL u=,len=strlen(s);
lenth_max=max(len,lenth_max);//记录字典里最长的单词长度
for(LL i=;i<len;i++)
{
LL c=s[i]-'a';
if(!ch[u][c]) ch[u][c]=++cnt;
u=ch[u][c];
}
bo[u]=;
}
inline bool find(LL l,LL r)
{
LL u=;
for(LL i=l;i<=r;i++)
{
LL c=s[i]-'a';
if(!ch[u][c]) return false;
u=ch[u][c];
}
return bo[u];
}
int main()
{
freopen("L.in","r",stdin);
freopen("L.out","w",stdout);
n=read();m=read();
for(LL i=;i<=n;i++)
{
scanf("%s",s);
insert(s);
}
for(LL i=;i<=m;i++)
{
memset(f,false,sizeof(f));ans=;
scanf("%s",s);
LL len=strlen(s);
for(LL j=;j<len;j++)
for(LL k=max(j-lenth_max,-INF);k<=j;k++)
if((k==-INF||f[k])&&(find(k+,j)))
{
f[j]=true;ans=j+;break;
}
printf("%lld\n",ans);
}
return ;
}
P2292 [HNOI2004]L语言的更多相关文章
- 洛谷 P2292 [HNOI2004] L语言 解题报告
P2292 [HNOI2004] L语言 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章\(T\)是由若干小写字母构成.一个单词 ...
- 洛谷:P2292 [HNOI2004]L语言(DP+Trie树)
P2292 [HNOI2004]L语言 题目链接:https://www.luogu.org/problemnew/show/P2292 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有 ...
- Luogu P2292 [HNOI2004]L语言(Trie+dp)
P2292 [HNOI2004]L语言 题面 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章 \(T\) 是由若干小写字母构成. ...
- 2021.11.09 P2292 [HNOI2004]L语言(trie树+AC自动机)
2021.11.09 P2292 [HNOI2004]L语言(trie树+AC自动机) https://www.luogu.com.cn/problem/P2292 题意: 标点符号的出现晚于文字的出 ...
- 洛谷(cogs 1293/bzoj 1212) P2292 [HNOI2004]L语言
1293. [HNOI2004] L语言 ★★★ 输入文件:language.in 输出文件:language.out 简单对比时间限制:1 s 内存限制:162 MB [题目描述] ...
- Luogu P2292 [HNOI2004]L语言
题目链接 \(Click\) \(Here\) 好久没写\(DP\)了真是水平下降不少,一眼把这个题搞成贪心了,然后一发交上只有\(37\)分\(QwQ\) 这个题好像还可以\(AC\)自动机胡搞?不 ...
- 洛谷P2292 [HNOI2004]L语言
传送门 建好trie树 当$dp[j]==1$当且仅当存在$dp[k]=1$且$T[k+1,j]==word[i]$ 然后乱搞就行了 //minamoto #include<iostream&g ...
- 洛谷 P2292 [HNOI2004]L语言
题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...
- 【Luogu】P2292 [HNOI2004]L语言 题解
前置芝士:\(Trie\)字典树 这道题,说是AC自动机,实际上一个\(Trie+\)队列轻松搞定. 首先,我们对所有单词建一棵\(Trie\). 然后,定义一个空队列\(Q\),初始时把\(-1\) ...
随机推荐
- Python学习之旅(十四)
Python基础知识(13):函数(Ⅳ) Python内置函数 1.abs:取绝对值 abs(-1) 1 2.all:把序列中的每一个元素拿出来做布尔运算,都为真则返回True,如果序列中有None. ...
- Python----Windous下安装python
一. python 安装 1. 下载安装包 https://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi # 2.7安装包 htt ...
- WebH
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...
- redis问题与解决思路
问题现象: 集群状态 1主 2从,主没有开启bgsave,从开启bgsave.现象所有redis可以访问,进行操作.主不断开始bgsave 1从停止bgsave. 主日志报错# Connection ...
- 解决HTML5提出的新的元素不被IE6-8识别的解决办法
解决HTML5提出的新的元素不被IE6-8识别的解决办法 <!--[if lt IE 9]> <script type="text/javascript" src ...
- zabbix结合grafana打造炫酷监控界面
一.grafana介绍 grafana是一个开源的数据展示工具, 是一个开箱即用的可视化工具,具有功能齐全的度量仪表盘和图形编辑器,有灵活丰富的图形化选项,可以混合多种风格,支持多个数据源特点. za ...
- [py]GTM和UTC及python的时间戳
时间戳是一串字符串 time.time() 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数.通俗的讲, 时间戳是一 ...
- node获取windows pc 机器的标示
var exec = require('child_process').exec; if(process.platform != "win32"){ //window throw ...
- 使用Sqlserver事务发布实现数据同步(zhuanqian)
事务的功能在sqlserver中由来已久,因为最近在做一个数据同步方案,所以有机会再次研究一下它以及快照等,发现还是有很多不错的功能和改进的.这里以sqlserver2008的事务发布功能为例,对发布 ...
- stl string的erase方法
; i < s.size(); i++) { ') { s.erase(i,); i--; } } 删除string中的所有0.