[UOJ#219][BZOJ4650][Noi2016]优秀的拆分 试题描述 如果一个字符串可以被拆分为 AABBAABB 的形式,其中 A 和 B 是任意非空字符串,则我们称该字符串的这种拆分是优秀的.例如,对于字符串 aabaabaa,如果令 A=aab,B=a,我们就找到了这个字符串拆分成 AABBAABB 的一种方式.一个字符串可能没有优秀的拆分,也可能存在不止一种优秀的拆分.比如我们令 A=a,B=baa,也可以用 AABBAABB 表示出上述字符串:但是,字符串 abaabaa 就没…
题目描述 如果一个字符串可以被拆分为AABBAABB的形式,其中 A和 B是任意非空字符串,则我们称该字符串的这种拆分是优秀的. 例如,对于字符串aabaabaaaabaabaa,如果令 A=aabA=aab,B=aB=a,我们就找到了这个字符串拆分成 AABBAABB的一种方式. 一个字符串可能没有优秀的拆分,也可能存在不止一种优秀的拆分.比如我们令 A=aA=a,B=baaB=baa,也可以用 AABBAABB表示出上述字符串:但是,字符串 abaabaaabaabaa 就没有优秀的拆分.…
传送门 题目可以转化为求\(AA\)的数量,设\(cnt1_x\)表示左端点为\(x\)的\(AA\)的数量,\(cnt2_x\)表示右端点为\(x\)的\(AA\)的数量,那么答案就是\(\sum cnt2_i \times cnt1_{i+1}\) 比较朴素的想法是枚举两个后缀然后哈希/SA判断这两个后缀的LCP是否足够长,能够拼成一个\(AA\)形式的串.然后这样就能拿95分??? 考虑\(n\)比较大的时候优化枚举.我们对于所有\(len \in [1,\frac{N}{2}]\),在串…
题目 如果一个字符串可以被拆分为 AABBAABB 的形式,其中 AA 和 BB 是任意非空字符串,则我们称该字符串的这种拆 分是优秀的.例如,对于字符串 aabaabaa,如果令 A=aabA=aab,B=aB=a,我们就找到了这个字符串拆分成 AABBA ABB 的一种方式.一个字符串可能没有优秀的拆分,也可能存在不止一种优秀的拆分.比如我们令 A=aA=a,B=baa B=baa,也可以用 AABBAABB 表示出上述字符串:但是,字符串 abaabaa 就没有优秀的拆分.现在给出一个长度…
题意 题目链接 Sol NOI的题都这么良心么.. 先交个\(n^4\)暴力 => 75 hash优化一下 => 90 然后\(90\)到\(100\)分之间至少差了\(10\)难度台阶= = \(90\)分的暴力hash就比较trival了. 考虑怎么优化. 显然我们只要找出所有形如\(AA\)的字符串就行了,设\(pre[i]\)表示以\(i\)为端点,向前的所有\(AA\)的数量,\(suf[i]\)表示以\(i\)为端点,向后的所有\(AA\)的数量 这样最终答案就是\(\sum_{i…
好气啊,没开longlong又biubiu了 底层: 用hash或者奇奇怪怪的算法兹磁logn求最长公共前后缀 思路: 统计出从一个点开始和结束的形如AA的子串的个数 统计的时候把相邻的结果相乘加起来就好了 #include <bits/stdc++.h> #define MOD 998244353 #define ad(x,y,z) t[x][y]++,t[x][z+1]-- using namespace std; long long T,n,LOG; char ch; ],t[][],m…
原文链接http://www.cnblogs.com/zhouzhendong/p/9025092.html 题目传送门 - UOJ#219 (推荐,题面清晰) 题目传送门 - BZOJ4650 题意 如果一个字符串可以被拆分为AABB的形式,其中AA和BB是任意非空字符串,则我们称该字符串的这种拆分是优秀的. 现在给出一个长度为n的字符串S,我们需要求出,在它所有子串的所有拆分方式中,优秀拆分的总个数.这里的子串是指字符串中连续的一段. 多组数据,数据组数$\leq 10,n\leq 3000…
考场上没秒的话多拿5分并不划算的样子. 思想其实很简单嘛. 要统计答案,求以每个位置开始和结束的AA串数量就好了.那么枚举AA中A的长度L,每L个字符设一个关键点,这样AA一定经过相邻的两个关键点.计算出相邻关键点的最长公共前后缀,把对应的位置区间加一下. 求lcp和lcs可以用后缀数组,也可以用hash. #include<bits/stdc++.h> #define N 30005 #define M (l+r+1>>1) using std::min; const int m…
显然只要求出以每个位置开始的AA串数量就可以了,将其和反串同位置的结果乘一下,加起来就是答案.考虑对每种长度的字符串计数.若当前考虑的A串长度为x,我们每隔x个字符设一个关键点,求出相邻两关键点的后缀lcp和前缀lcs,交叉部分就是跨过这两个关键点的A串长度为x的AA串个数.差分一发就能对每个位置求了. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include…
关于解法这个讲的很清楚了,主要用了设关键点的巧妙思想. 主要想说的是一个刚学的方法:通过后缀自动机建立后缀树,再转成后缀数组. 后缀数组功能强大,但是最令人头疼的地方是模板太难背容易写错.用这个方法,只需要用上SAM的模板即可. https://blog.csdn.net/lvzelong2014/article/details/79006541 反串后缀自动机的parent树就是原串的后缀树,一遍DFS即可求出后缀数组. 这样代码复杂度上可能稍简单些(在忘记SA模板的时候可以用),构建过程的复…