Day1
queue
Analysis
先考虑一种最暴力的算法:使用哈希表储存所有长度不超过K=50的子串,合并和分裂时我们只用修改交界处的K2个子串。时间复杂度O(mK2)。
考虑精细地实现程序:合并时我们只插入原本没有插入过的,也就是严格跨边界的。虽然单次复杂度可能达到O(K2),但是均摊意义下是可以保证复杂度的:
设势函数Φ表示哈希表里面的串的个数,显然Φ有上界O(nK)。合并时每一次插入字符串我们相当于用O(1)的复杂度增加了O(1)的势能。删除的时候我们每次会减少O(K2)的势能。因此总的复杂度是O(nK+cK2)的。
为了减少算法常数,我们可以考虑用Trie树来代替哈希表,为了方便地迭代计算我们还要在每一个节点上处理出一个后继指针表示其删掉当前字符串的第一个字符它会跳到哪一个节点。注意求答案的时候跳到空节点我们就可以退出了。Trie的大小开O(nK+cK2)就好了。
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cctype>
using namespace std;
int read()
{
int x=0,f=1;
char ch=getchar();
while (!isdigit(ch)) f=ch=='-'?-