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\) ...
随机推荐
- PHP指定时间戳/日期加一天,一年,一周,一月
PHP指定时间戳加上1天,1周,1月,一年其实是不需要用上什么函数的!指定时间戳本身就是数字整型,我们只需要再计算1天,1周它的秒数相加即可! 博主搜索php指定时间戳加一天一年,结果许多的文章给出来 ...
- .net 问题
1.socket初始化三个步骤 2.多线程 3.mvc的理解
- ng2-tree
[转]https://github.com/valor-software/ng2-tree#eyes-demo demo:http://valor-software.com/ng2-tree/
- Java ee第四周作业
代码下载链接:https://github.com/javaee/tutorial-examples/tree/master/web/jsf/hello1 代码内容: /*** Copyright ( ...
- rebuild online时意外中断 再次重建时报错解决方法
rebuild online时意外中断 再次重建时报错 SQL> alter index PARTY.IDX_CM_INDIV_CUSTOMER_4 rebuild online; alter ...
- maven工程下添加oracle驱动包
maven工程手动安装oracle驱动包到本地仓库 下载ojdbc.jar包 这个当然是最好去官网下载了.http://mvnrepository.com这个仓库上有,具体页面地址为: http:// ...
- DAX/PowerBI系列 - 库存总价值(Inventory Value)
DAX/PowerBI系列 - 库存总价值(Inventory Value) 欢迎交流与骚扰 难度: ★★☆☆☆(2星) 适用: ★★☆☆☆(2星) 概况: 有多少货(库存)当然重要(对于运营人员), ...
- 2018-2019-1 20189203《linux内核原理与分析》第六周作业
第一部分 给Menu OS增加命令 输入命令 rm -rf menu git clone http://github.com/mengning/menu.git make rootfs 查看增加的ti ...
- 实验一:C++简单程序设计
[实验一] #2-28 实现一个简单的菜单程序,运行时显示“Menu:A(dd) D(elete) S(ort) Q(uit),Selete one:”提示用户输入.A表示增加,D表示删除,S表示排序 ...
- arch----------arch下的一些命令,亲测
1.taoyanghao 不在 sudoers 文件中.此事将被报告. 这个是使用sudo以后报出的错误提示,sudo确定已经安装了. 解决方案:编辑/etc/sudoers文件.找到这一 行:&qu ...