传送门 思路 设\(dp_i\)表示以\(i\)结尾的\(A\)串,能达到的最长长度. 然后发现这显然可以\(i\)往自己控制的\(k\)连边,\(k\)往能匹配的\(j\)连边,就是个最长路,只要建出图来就完事了. 显然可以用数据结构得到两点之间是否有边,于是就获得了40分的好成绩. 考虑优化这个建图,字符串也就那么几个数据结构,那就后缀树吧. 有了后缀树,可以发现\(k\)会向\(k\)所在的节点的子树连边,注意不包括\(k\)自己的节点. 那么自己节点怎么办呢?把在这里的所有串拆开然后按长…
LOJ BZOJ 洛谷 对这题无话可说,确实比较...裸... 像dls说的拿拓扑和parent树一套就能出出来了... 另外表示BZOJ Rank1 tql... 暴力的话,由每个\(A_i\)向它能支配的\(B_j\)连边,再由\(B_j\)向它能匹配的\(A_k\)(是\(A_k\)的前缀)连边,拓扑DP就可以了. 正解就是优化建图方式. 把串反过来,\(B_j\)能匹配\(A_k\)就是\(B_j\)是\(A_k\)的后缀,换句话说\(B_j\)能匹配\(parent\)树中它子树的所有…
题面 传送门 题解 首先,我们把串反过来,那么前缀就变成后缀,建一个\(SAM\).我们发现一个节点的后缀是它的所有祖先 那么我们是不是直接按着\(parent\)树建边就可以了呢? 显然不是.我们假设在\(SAM\)的某个节点上同时存在某个\(a_i\)和\(b_j\)且\(|b_j|>|a_i|\),\(b_j\)不是\(a_i\)的后缀,但它们仍然有边相连!(自己到自己就当有边吧--) 对于每一个节点,我们把处于这个节点中的所有串排个序,按长度为第一关键字,是否是\(B\)串为第二关键字.…
题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的时间就会爆炸,显然不能暴力连边. 对于前缀不好解决,可以将字符串翻转然后变成判断是否是后缀. 可以发现对于后缀自动机的$parent$树,每个节点是子树内所有节点的后缀. 那么我们可以利用$parent$树来优化建图过程,将树上每个点向子节点连边. 对于每个$A$串和$B$串在后缀自动机上匹配出对应…
LOJ 洛谷 考场上都拍上了,8:50才发现我读错了题=-= 两天都读错题...醉惹... \(Solution1\) 先求一遍前缀异或和. 假设左端点是\(i\),那么我们要在\([i,n]\)中找一个\(sum_j\)使得它和\(sum_{i-1}\)异或最大.可以可持久化Trie. 对\(i\in[1,n]\)都求一遍它能得到的最大的异或值,扔到堆里. 每次从堆里找出值最大的,假设是\(x\),与\(sum_{x-1}\)异或得到最大值的数是\(sum_y\),那么之后就不能选\(sum_…
啊啊啊边界判错了搞死我了QAQ 这题是一个想起来很休闲写起来很恶心的背包 对于\(k=0\)的情况,可以发现选阵营和选派系是独立的,对选城市选阵营和学校选派系分别跑一遍01背包就行了 对于\(k>0\)的情况,设\(f[i][0/1][j][k]\)表示对于第\(i\)个有限制的学校,该学校选择\(0/1\)阵营时,\(C0\)阵营有\(j\)人,\(D0\)派系有\(k\)人的方案数 转移要分类讨论,有点麻烦,看代码吧 // luogu-judger-enable-o2 #include <…
题目:https://www.luogu.org/problemnew/show/P5291 考场上写了 16 分的.不过只得了 4 分. 对于一个救援范围,其中合法的点集也是一个连通块. 2n 枚举一个救援范围,然后换根 DP 一下范围内的每个点开始的最长链,那些最长链 <=L 的点就是该范围的合法点集. 这样得到每个合法点集出现的方案, 与卷积 k 次即可.卷积的时候先 FWT 成点值,然后快速幂一样乘 k 次,再 FWT 回来即可. 但只有 4 分.过不了大样例. #include<cs…
这是一道涵盖了字符串.图论.数据结构三个方面的综合大题. 把这道题放在D1T2的人应该拖出去打 前置芝士 首先,您至少要会topsort. 其次,如果您只想拿个暴力分,字符串Hash就足够了:如果您想拿满分,SA和SAM您至少要会一种(本文采用SA). 最后,正解还需要您了解线段树优化建边,并在此基础上用主席树实现. 暴力算法一 对于测试点1~4,暴力建图,Hash优化,可以拿到40分的高分. #include <bits/stdc++.h> #define ll long long #def…
好难写的字符串+数据结构问题,写+调了一下午的说 首先理解题意后我们对问题进行转化,对于每个字符串我们用一个点来代表它们,其中\(A\)类串的点权为它们的长度,\(B\)类串的权值为\(0\) 这样我们根据题意把\(A\to B\)的边连起来,同时每个\(B\)类串向所有以其为前缀的\(A\)类串连边 这样我们就得到了一张DAG(如果不是的话就输出\(-1\)),然后对于它拓扑排序之后求权值和最大链即可 但是第二类边该怎么连呢,下面我们来分析一下具体操作 SA转化问题 首先关于这种前后缀相关的问…
原题传送门 我用sa做的本题 (码量似乎有点大) 先对原串建sa 考虑如何建图: 从大到小枚举长度len 先将height中等于len的两个位置在并查集合并起来,将lst也合并(lst是链表) 再将长度为len的a串的编号加入所在并查集的lst 然后就珂以查询出每个长度为len的b串所对应a串编号的链表头尾 处理完所有后按加入链表的顺序重新编号 (上面这段见merging函数,语文不好说不清) 现在每个b对应的a的编号都是一段连续的区间 珂以用线段树优化建图 最后跑一下拓扑排序即可得出答案 #i…