实用数据结构整理
实用数据结构
1 基础数据结构回顾
1.1 抽象数据类型(ADT)
基础的栈、队列……
1.2 优先队列
priority_queue;
堆优化的队列(常数是make_heap的好几倍)
1.3 并查集
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
时间复杂度:O(α(x))//α(x)<=4
2 区间信息的维护与查询
2.1 二叉索引树(树状数组)
int lowbit(int &x){
return x&-x;
}
void updata(int p,int v){
for(int i=p;i<=n;i+=lowbit(i)) c[i]+=v;
}
int query(int p){
int res=0;
for(int i=p;i;i-=lowbit(i)) res+=c[i];
return res;
}
1)单点修改,区间求和:
updata(x,y);//O(log2(n))
printf("%d\n",query(y)-query(x-1));//O(log2(n))
2)区间修改,单点查询:
updata(x,z);updata(y+1,-z);;//O(log2(n))
printf("%d\n",query(x));//O(log2(n))
2.2 RMQ问题
1)对于max/min问题:
预处理:O(nlog2(n))//log2(n)<=20
查询:O(1)
修改:等价<=>预处理
2)对于其他问题(如求和,etc):
建议不要用
2.3 线段树(1):点修改
建树:O(nlog2(n))
单次修改:O(log2(n))
单次查询:O(log2(n))
空间支撑:4*n
2.4 线段树(2):区间修改
建树:O(nlog2(n))
加上lazy-tage
单次修改:<= O(log2(n))
单次查询:<= O(log2(n))
(数据量越大,lazy-tage优化越明显)
空间支撑:4*n
3 字符串(1)
3.1 Trie
预处理:O(maxlen*kinds)//maxlen为最大字符串长度,kinds为所有字符串中字符种类数目
查询:O(logn)
3.2 KMP算法
预处理:O(n):fail[]/next[]
查询:O(n)匹配
3.3 Manacher算法
O(n):p[i]往两边扩展,更新id,mx
3.4 Aho-Corasick自动机
Trie的升级版,加了队列处理
//以下不会
4 字符串(2)
4.1 后缀数组
4.2 最长公共前缀(LCP)
4.3 基于哈希值的LCP算法
5 排序二叉树
5.1 基本概念
5.2 用Treap实现名次树
5.3 用伸展树实现可分裂与合并的序列