P4022-[CTSC2012]熟悉的文章【广义SAM,dp,单调队列】
正题
题目链接:https://www.luogu.com.cn/problem/P4022
题目大意
给出\(m\)个模板串。
然后\(n\)次询问给出一个串\(S\)要求找到一个最大的\(L\)使得能够将\(S\)超过\(90\%\)的部分拿出来分后每个串都是某个模板串的子串且长度不小于\(L\)。
所有输入文件长度不超过 \(1100000\) 字节。字符集为\(\{0,1\}\)
解题思路
先把模板串拿出来构一个广义SAM,然后考虑用这个对串进行匹配。
先对于每个位置求出一个\(len_i\)表示一个最长的长度使得\(i\)的后缀是某个模板串的子串。
然后考虑二分一个\(L\)后进行\(dp\)。
那么有
\]
因为\(i-len_i\)单调所以把\(j\)丢进单调队列里就好了。
时间复杂度\(O(n\log n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1200000;
int n,m,cnt,f[N],q[N],ml[N];
int ch[N][2],len[N],fa[N];
char s[N];
int Insert(int p,int c){
if(ch[p][c]){
int q=ch[p][c];
if(len[p]+1==len[q])return q;
else{
int nq=++cnt;len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[nq]));
fa[nq]=fa[q];fa[q]=nq;
for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;
return nq;
}
}
int np=++cnt;len[np]=len[p]+1;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=1;
else{
int q=ch[p][c];
if(len[p]+1==len[q])fa[np]=q;
else{
int nq=++cnt;len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[nq]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
return np;
}
bool check(int L,int n){
int head=1,tail=0,ans=0;
for(int i=1;i<=n;i++){
if(i>=L){
int j=i-L;
while(head<=tail&&f[j]-j>f[q[tail]]-q[tail])tail--;
q[++tail]=j;
}
while(head<=tail&&q[head]<i-ml[i])head++;
f[i]=0;
if(head<=tail)f[i]=f[q[head]]+i-q[head];
f[i]=max(f[i],f[i-1]);
ans=max(ans,f[i]);
}
return (ans*10>=n*9);
}
int main()
{
scanf("%d%d",&n,&m);cnt=1;
for(int i=1;i<=m;i++){
scanf("%s",s+1);
int l=strlen(s+1),x=1;
for(int j=1;j<=l;j++)
x=Insert(x,s[j]-'0');
}
while(n--){
scanf("%s",s+1);
int sl=strlen(s+1),x=1,L=0;
for(int i=1;i<=sl;i++){
int c=s[i]-'0';
while(x&&!ch[x][c])
{x=fa[x];L=len[x];}
if(x)x=ch[x][c],L++;
else x=1,L=0;
ml[i]=L;
}
int l=1,r=sl;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid,sl))l=mid+1;
else r=mid-1;
}
printf("%d\n",r);
}
return 0;
}
P4022-[CTSC2012]熟悉的文章【广义SAM,dp,单调队列】的更多相关文章
- Luogu4022 CTSC2012 熟悉的文章 广义SAM、二分答案、单调队列
传送门 先将所有模板串扔进广义SAM.发现作文的\(L0\)具有单调性,即\(L0\)更小不会影响答案,所以二分答案. 假设当前二分的值为\(mid\),将当前的作文放到广义SAM上匹配. 设对于第\ ...
- [CTSC2012]熟悉的文章 (后缀自动机 单调队列)
/* 首先答案显然是具有单调性的, 所以可以二分进行判断 然后当我们二分过后考虑dp来求最长匹配个数, 发现每个点能够转移的地点 肯定是一段区间, 然后这样就能够得到一个log^2算法 至于每个点的匹 ...
- P4022 [CTSC2012]熟悉的文章
题目 P4022 [CTSC2012]熟悉的文章 题目大意:多个文本串,多个匹配串,我们求\(L\),\(L\)指(匹配串中\(≥L\)长度的子串出现在文本串才为"熟悉",使得匹配 ...
- CTSC2012 熟悉的文章 广义后缀自动机_单调队列
没啥难的,主要是单调队列忘了咋求了QAQ... Code: #include <cstdio> #include <algorithm> #include <cstrin ...
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)
codevs 1748 瑰丽华尔兹 2005年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Descripti ...
- 习题:烽火传递(DP+单调队列)
烽火传递[题目描述]烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上.一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情.在某两座城市之间有n个烽火台,每个烽火台 ...
- (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- 3622 假期(DP+单调队列优化)
3622 假期 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 经过几个月辛勤的工作,FJ决定让奶牛放假.假期可以在1-N天内任意选择 ...
随机推荐
- C++类构造函数、拷贝构造函数、复制构造函数、复制构造函数、构造函数显示调用和隐式调用
一. 构造函数是干什么的 class Counter { public: // 类Counter的构造函数 // 特点:以类名作为函数名,无返回 ...
- CentOS8安装Mysql5.7
检查是否安装mysql [root@iZ2ze8crquorxf6c7l0eluZ ~]# rpm -qa |grep mysql [root@iZ2ze8crquorxf6c7l0eluZ ~]# ...
- bootStrap模态框与select2合用时input不能获取焦点、模态框内部滑动,select选中跳转
bootStrap模态框与select2合用时input不能获取焦点 在bootstrap的模态框里使用select2插件,会导致select2里的input输入框没有办法获得焦点,没有办法输入. 把 ...
- 简析时序数据库 InfluxDB
时序数据基础 时序数据特点 时序数据TimeSeries是一连串随时间推移而发生变化的相关事件. 以下图的 CPU 监控数据为例,同个 IP 的相关监控数据组成了一条时序数据,不相关数据则分布在不同的 ...
- ubuntu中用update-alternatives进行软件多版本设置、切换,以python配置为例
以Python2.7和Python3.5设置为例: 在系统中添加Python2.7.Python3.5的选项,默认为Python3.5 sudo update-alternatives --insta ...
- ROS catkin_make error Could not find a package configuration file provided by "actionlib_msgs"
在使用ROS catkin_make编译的时候,出现类似如下错误 CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkinConfig.cma ...
- MySQL的几种锁机制的使用介绍
锁 在日常的开发过程中,为了控制线程的并发肯定会用到锁机制.对于数据库而言,锁机制就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则.当然MySQL也不例外,根据不同 ...
- Spring依赖注入的四种方式
首先,我们需要定义一个Bean的class类: package framework.spring; import org.springframework.beans.BeansException; i ...
- 用XPath定位Web页面元素时,如何快速验证XPath语句是否正确?
在使用Selenium做Web UI自动化测试的过程中,XPath是一种定位页面元素的常用方式.然而,面对某些元素的XPath路径过于复杂,我们想快速验证拼凑的Xpath语句是否正确时,该怎么办呢?这 ...
- Redis核心原理与实践--字符串实现原理
Redis是一个键值对数据库(key-value DB),下面是一个简单的Redis的命令: > SET msg "hello wolrd" 该命令将键"msg&q ...