热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

洛谷P4022[CTSC2012]熟悉的文章广义后缀自动机+d

题目大意:有多个主串,每次询问将询问串分成多个连续子串,如果一个子串长度≥L≥L≥L且在主串中出现过就是合法的如果合法的子串总长度≥≥≥询

题目大意:
有多个主串,每次询问将询问串分成多个连续子串,如果一个子串长度≥L≥LL且在主串中出现过就是合法的
如果合法的子串总长度≥≥询问串长的90%90\%90%,这个串就是合法的字符串,求使得询问串成为合法的字符串的最大的LLL

分析:
我们可以二分答案,显然答案越大可以使用的合法串就越多,而且是包含关系,满足二分性。
我们把这些串建一个广义后缀自动机。
f[i]f[i]f[i]iii个位置最多可以覆盖多少个位置。
显然有
f[i]=max(f[i−1],f[j]+i−j)j∈[i−maxc,i−midlen]f[i]=max(f[i-1],f[j]+i-j) j\in[i-maxc,i-midlen]f[i]=max(f[i1],f[j]+ij)j[imaxc,imidlen]
其中maxcmaxcmaxc是以当前位置结尾的询问串后缀在所有主串中的lcslcslcs
这个可以在后缀自动机上跳failfailfail
分三种情况讨论,如果当前节点有儿子,直接往儿子走,maxlen+1。
如果当前点没有这个儿子,跳fail到有这个儿子的节点,显然这个节点代表的串都是可以的(因为后缀自动机每个节点代表不止一个串,但是都是后缀关系),那么显然取最长那个,即maxlen=t[x].len+1maxlen=t[x].len+1maxlen=t[x].len+1
如果没有找到儿子,直接maxlen=0maxlen=0maxlen=0

代码:

#include
#include
#include
#include const int maxn=3e6+7;using namespace std;int n,m,cnt,len,head,tail;
int f[maxn],q[maxn];
char s[maxn];struct node{int len,fail;int son[2];
}t[maxn];struct rec{int son[2];
}a[maxn];void ins()
{int now&#61;1;len&#61;strlen(s&#43;1);for (int i&#61;1;i<&#61;len;i&#43;&#43;){int c&#61;s[i]-&#39;0&#39;;if (!a[now].son[c]) a[now].son[c]&#61;&#43;&#43;cnt;now&#61;a[now].son[c];}
}int ins_sam(int x,int c)
{int now,p,q,clone;p&#61;x;if (t[p].son[c]){q&#61;t[p].son[c];if (t[p].len&#43;1&#61;&#61;t[q].len) return q;clone&#61;&#43;&#43;cnt;t[clone]&#61;t[q];t[clone].len&#61;t[p].len&#43;1;t[q].fail&#61;clone;while (p&&(t[p].son[c]&#61;&#61;q)) t[p].son[c]&#61;clone,p&#61;t[p].fail;return clone;}now&#61;&#43;&#43;cnt;t[now].len&#61;t[p].len&#43;1;while (p&&(!t[p].son[c])) t[p].son[c]&#61;now,p&#61;t[p].fail;if (!p) t[now].fail&#61;1;else{q&#61;t[p].son[c];if (t[p].len&#43;1&#61;&#61;t[q].len) t[now].fail&#61;q;else{clone&#61;&#43;&#43;cnt;t[clone]&#61;t[q];t[clone].len&#61;t[p].len&#43;1;t[now].fail&#61;t[q].fail&#61;clone;while (p&&(t[p].son[c]&#61;&#61;q)) t[p].son[c]&#61;clone,p&#61;t[p].fail;}}return now;
}void dfs(int x,int last)
{int d;if (a[x].son[0]){d&#61;ins_sam(last,0);dfs(a[x].son[0],d);}if (a[x].son[1]){d&#61;ins_sam(last,1);dfs(a[x].son[1],d);}
}bool check(int k)
{int p&#61;1,maxlen&#61;0;f[0]&#61;0;head&#61;1,tail&#61;0; for (int i&#61;1;i<&#61;len;i&#43;&#43;){int c&#61;s[i]-&#39;0&#39;;if (t[p].son[c]) maxlen&#43;&#43;,p&#61;t[p].son[c];else{while (p&&(!t[p].son[c])) p&#61;t[p].fail;if (!p) p&#61;1,maxlen&#61;0;else{maxlen&#61;t[p].len&#43;1;p&#61;t[p].son[c];}}f[i]&#61;f[i-1];if (i-k>&#61;0) q[&#43;&#43;tail]&#61;i-k;while ((head&#61;f[q[tail-1]]-q[tail-1])) q[tail-1]&#61;q[tail],tail--;if (maxlen>&#61;k){ while (q[head]&#61;len*9;
}int main()
{scanf("%d%d",&m,&n);cnt&#61;1; for (int i&#61;1;i<&#61;n;i&#43;&#43;){scanf("%s",s&#43;1);ins();} cnt&#61;1; dfs(1,1);for (int i&#61;1;i<&#61;m;i&#43;&#43;){scanf("%s",s&#43;1); len&#61;strlen(s&#43;1); int l&#61;1,r&#61;len,ans&#61;0;while (l<&#61;r){int mid&#61;(l&#43;r)/2;if (check(mid)) l&#61;mid&#43;1,ans&#61;mid;else r&#61;mid-1;}printf("%d\n",ans);}
}


推荐阅读
  • 题目链接:POJ 2777。问题描述:给定一个区域,需要进行多次涂色操作,并在每次操作后查询某个区间内的不同颜色数量。解决方案:由于题目中颜色种类不超过30种,可以利用线段树的懒惰更新策略来高效处理这些操作。通过懒惰标记,避免了不必要的节点更新,从而显著提高了算法的效率。此外,该方法还能有效应对大规模数据输入,确保在合理的时间内完成所有操作。 ... [详细]
  • 在HDU 1166敌军布阵问题中,通过运用线段树数据结构,可以高效地计算指定区间的敌军数量。该算法不仅能够在限定的时间和内存条件下快速求解,还能够灵活应对动态变化的战场局势,为实时决策提供支持。 ... [详细]
  • 每日精选Codeforces训练题:1119E(贪心算法)、821C(栈模拟)和645D(拓扑排序)
    题目涉及三种不同类型的算法问题:1119E(贪心算法)、821C(栈模拟)和645D(拓扑排序)。其中,1119E的问题背景是有n种不同长度的棍子,长度分别为2^0, 2^1, …, 2^(n-1),每种棍子的数量为a[i]。任务是计算可以组成的三角形数量。根据三角形的性质,任意两边之和必须大于第三边。该问题可以通过贪心算法高效解决,通过合理选择棍子组合来最大化三角形的数量。 ... [详细]
  • 本文详细解析了九度编程平台上的斐波那契数列高效算法挑战(题目编号:1387)。该挑战要求在1秒的时间限制和32兆的内存限制下,设计出高效的斐波那契数列计算方法。通过多种算法的对比和性能分析,本文提供了优化方案,帮助参赛者在限定资源条件下实现高效计算。 ... [详细]
  • 如何利用正则表达式(regexp)实现高效的模式匹配?本文探讨了正则表达式在编程中的应用,并分析了一个示例程序中存在的问题。通过具体的代码示例,指出该程序在定义和使用正则表达式时的不当之处,旨在帮助读者更好地理解和应用正则表达式技术。 ... [详细]
  • 基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析
    基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析 ... [详细]
  • 在晴朗天气条件下,对一种神奇的魔法现象进行了深入分析。该题目为原创,基准时间限制为1秒,空间限制为131072KB,分值20,属于3级难度的算法题。研究发现,这种魔法现象在阳光明媚的环境中表现得尤为显著,进一步探讨了其背后的科学原理和技术实现方法。 ... [详细]
  • 在2021-2022 ACM集训队月度编程挑战赛第二轮中,题目“最大值与最小值的选择”要求参赛者处理一个包含n个元素的数组,并给定一个整数k。任务是通过选择特定的子数组,计算并返回这些子数组的最大值和最小值之间的差值。该问题考验了选手对数组操作和优化算法的理解与应用能力。 ... [详细]
  • 寻找最长无重复字符的子字符串 ... [详细]
  • HDU1176:免费馅饼问题的动态规划解法分析
    题目“免费馅饼”通过动态规划方法进行了解析。该问题的时间限制为 Java 2000ms 和其他语言 1000ms,内存限制为 Java 65536K 和其他语言 32768K。本文详细探讨了如何利用动态规划算法高效求解此问题,并对算法的时间复杂度和空间复杂度进行了深入分析。此外,还提供了具体的实现步骤和代码示例,帮助读者更好地理解和应用这一方法。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • 开发心得:成为SGU475智能筏工的策略与技巧 ... [详细]
  • 在 Windows 10 环境中,通过配置 Visual Studio Code (VSCode) 实现基于 Windows Subsystem for Linux (WSL) 的 C++ 开发,并启用智能代码提示功能。具体步骤包括安装 VSCode 及其相关插件,如 CCIntelliSense、TabNine 和 BracketPairColorizer,确保在 WSL 中顺利进行开发工作。此外,还详细介绍了如何在 Windows 10 中启用和配置 WSL,以实现无缝的跨平台开发体验。 ... [详细]
  • Go 项目中数据库配置文件的优化与应用 ... [详细]
  • 在C语言中,定义一个包含学号、姓名和年龄的学生信息结构体,并遵循严格的命名规范。首先,初始化结构体变量的所有成员为默认值,然后将其学号设为88,姓名设为“liming”,年龄设为25。最后,在控制台上输出该结构体变量的详细信息,以验证数据的正确性。例如,使用 `typedef struct Student` 定义结构体类型。 ... [详细]
author-avatar
橙橙_贲1999
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有