2021.2.1做题小结

1.[CF126B]Password

题意:找到既是母串前缀又是母串后缀,也是母串中间一部分的字串

思路:法1:通过 exkmp,求得 z 数组通过exkmp[i]+i==len判断出这个串既是前缀又是后缀 ,maxn记录当前最大的exkmp,如果说我们已经找到了一个后缀前缀,并且在i前面的最大的exkmp[i]是要比n-i长的,说明在中间至少也出现了一个相同的子串

法2:kmp,找一个既是S的前缀又是S的后缀同时又在S中间出现过的最长子串,其实就是找一个从0开始的一个子串使得它的nxt>=nxt[len],从2枚举到n-1这样可以保证既不是前缀也不是后缀,,如果next[i]=next[n]那么就找到了最大的子串,注意如果 next[n]>max(next[1...n-1]) 时显然无法找到

法3:对于一个前缀 T,如果存在一个不在最左边也不在最右边的子串 U,那么一个比 T 短的前缀也一定能找到对应的 U'。所以:1.O(n) 找出所有合法的前缀 T(有对应的后缀),2.二分,判断是否存在 U O(n) 判,总复杂度 O(nlogn)

法4:正反两次kmp 我们可以发现一个切入点:对于我们找到的一个满足条件的字符串 P(假设它在S中的起始和终点坐标分别为l,r),那么我们发现(设 |S|=n):P 既是 S[1...r] 的前缀,也是 S[1...r] 的后缀 P 既是 S[l...n] 的前缀,也是 S[l...n] 的后缀

法5:xkmp + hash 乱搞:exkmp求出自匹配数组,然后 hash 得到所有后缀存入map,枚举 exkmp,map判断是否存在相应后缀(好像没分)

注:思路大部分来自luogu

2.[CF432D] Prefixes and Suffixes

题意:求‘完美子串’:既是它的前缀也是它的后缀 个数并统计出现次数

思路:设以 i 结尾的‘完美串’出现了 num[i] 次,有:for(int i=len;i>=1;i--)num[kmp[i]]+=num[i]; 即若 i 为完美串出现num[i]此,则 num[kmp[i]] 也会出现 num[i] 次

3.前缀统计

题意:给定一些字符串,询问其中是串 T 的前缀个数

思路:Trie 裸题

4.The XOR Largest Pair

题意:在给定的N个整数A1,A2……An中选出两个进行XOR运算,求得到的最大结果

思路:将整数转为二进制,插入 trie 树,然后枚举每一个整数,容易在树中找到与其异或值最大的一个。取每次枚举结果 max 即可

注意:取出整数 X 的第 i 位二进制:(X>>i)&1;

变式:带权树,求最大的两点之间路径的异或值

思路:由于一个数异或两次等于不异或,所以可以求出点到根的异或值,将这些异或值插入Trie,即转化成上题

5.前缀

题意:一个字符串集合,从中找出一些字符串,使得找出来的这些字符串的最长公共前缀与这些字符串数的总个数的乘积最大化

思路:首先发现的一个问题是内存不够用,所以需要单向链表型trie

下一个问题是求这些字符串的最长公共前缀与这些字符串数的总个数的乘积

由 Trie 这样一棵树的形态可以发现,对于一个节点 u ,它的深度就是‘最长公共前缀’,它被字符串经过的次数就是‘这些字符串数的总个数’。于是可以在插入的时候顺便求出值,取max即可

6.[USACO2016DEC]Lasers_and_Mirrors

题意:http://fzuoj.xndxfz.com/problem/3409

思路:离散化+bfs,这里对于坐标的离散化需要把 x,y 分别排序去重

7.[TJOI2010]阅读理解

题意:http://fzuoj.xndxfz.com/problem/4136

思路:时间与空间取平衡(此题空间限制较严苛)

暴力思路,对于每一个询问去扫前面所有的文章。复杂度 O(M∑|S|),估计连部分分都拿不到。

30pts:用一个 set 记录每一篇文章有的字符串。每一次询问时,分别去每一个 set 里查询是否存在即可。复杂度是 O(NM|s|logL),相比于前面的做法优秀很多,如果复杂度优秀的话可以勉强 AC,但并不是最好的做法

100pts:用 Trie 维护这些字符串,单次复杂度省去一个 log,只有 O(NM|s|)。

也可直接 map

8.[POJ2001」Shortest Prefixes

题意:给你若干个单词的字典,求字典中每一个单词的最短唯一前缀。

思路:实际上就是找 Trie 中 前缀数域 为1的位置

### 1.[CF126B]Password
题意:找到既是母串前缀又是母串后缀,也是母串中间一部分的字串
思路:法1:通过 exkmp,求得 z 数组通过exkmp[i]+i==len判断出这个串既是前缀又是后缀 ,maxn记录当前最大的exkmp,如果说我们已经找到了一个后缀前缀,并且在i前面的最大的exkmp[i]是要比n-i长的,说明在中间至少也出现了一个相同的子串
法2:kmp,找一个既是S的前缀又是S的后缀同时又在S中间出现过的最长子串,其实就是找一个从0开始的一个子串使得它的nxt>=nxt[len],从2枚举到n-1这样可以保证既不是前缀也不是后缀,,如果next[i]=next[n]那么就找到了最大的子串,注意如果 next[n]>max(next[1...n-1]) 时显然无法找到
法3:对于一个前缀 T,如果存在一个不在最左边也不在最右边的子串 U,那么一个比 T 短的前缀也一定能找到对应的 U'。所以:1.O(n) 找出所有合法的前缀 T(有对应的后缀),2.二分,判断是否存在 U O(n) 判,总复杂度 O(nlogn)
法4:正反两次kmp 我们可以发现一个切入点:对于我们找到的一个满足条件的字符串 P(假设它在S中的起始和终点坐标分别为l,r),那么我们发现(设 |S|=n):P 既是 S[1...r] 的前缀,也是 S[1...r] 的后缀  P 既是 S[l...n] 的前缀,也是 S[l...n] 的后缀
法5:xkmp + hash 乱搞:exkmp求出自匹配数组,然后 hash 得到所有后缀存入map,枚举 exkmp,map判断是否存在相应后缀(好像没分)
注:思路大部分来自luogu
### 2.[CF432D] Prefixes and Suffixes
题意:求‘完美子串’:既是它的前缀也是它的后缀 个数并统计出现次数
思路:设以 i 结尾的‘完美串’出现了 num[i] 次,有:for(int i=len;i>=1;i--)num[kmp[i]]+=num[i]; 即若 i 为完美串出现num[i]此,则 num[kmp[i]] 也会出现 num[i] 次
### 3.前缀统计
题意:给定一些字符串,询问其中是串 T 的前缀个数
思路:Trie 裸题
### 4.The XOR Largest Pair
题意:在给定的N个整数A1,A2……An中选出两个进行XOR运算,求得到的最大结果
思路:将整数转为二进制,插入 trie 树,然后枚举每一个整数,容易在树中找到与其异或值最大的一个。取每次枚举结果 max 即可
注意:取出整数 X 的第 i 位二进制:(X>>i)&1;
变式:带权树,求最大的两点之间路径的异或值
思路:由于一个数异或两次等于不异或,所以可以求出点到根的异或值,将这些异或值插入Trie,即转化成上题
### 5.前缀
题意:一个字符串集合,从中找出一些字符串,使得找出来的这些字符串的最长公共前缀与这些字符串数的总个数的乘积最大化
思路:首先发现的一个问题是内存不够用,所以需要单向链表型trie 
  下一个问题是求这些字符串的最长公共前缀与这些字符串数的总个数的乘积    由 Trie 这样一棵树的形态可以发现,对于一个节点 u ,它的深度就是‘最长公共前缀’,它被字符串经过的次数就是‘这些字符串数的总个数’。于是可以在插入的时候顺便求出值,取max即可  ### 6.[USACO2016DEC]Lasers_and_Mirrors
题意:http://fzuoj.xndxfz.com/problem/3409
思路:离散化+bfs,这里对于坐标的离散化需要把 x,y 分别排序去重
### 7.[TJOI2010]阅读理解
题意:http://fzuoj.xndxfz.com/problem/4136
思路:时间与空间取平衡(此题空间限制较严苛)
暴力思路,对于每一个询问去扫前面所有的文章。复杂度 O(M∑|S|),估计连部分分都拿不到。
30pts:用一个 set 记录每一篇文章有的字符串。每一次询问时,分别去每一个 set 里查询是否存在即可。复杂度是 O(NM|s|logL),相比于前面的做法优秀很多,如果复杂度优秀的话可以勉强 AC,但并不是最好的做法
100pts:用 Trie 维护这些字符串,单次复杂度省去一个 log,只有 O(NM|s|)。
  也可直接 map  ### 8.[POJ2001」Shortest Prefixes
题意:给你若干个单词的字典,求字典中每一个单词的最短唯一前缀。
思路:实际上就是找 Trie 中 前缀数域 为1的位置

posted @ 2021-02-01 21:11  _Famiglistimo  阅读(131)  评论(0编辑  收藏  举报