一天天的为了啥。|

lgh_2009

园龄:1年粉丝:1关注:0

基础数据结构 学习笔记

1. 栈

1.1 栈的性质

后进先出。

1.2 栈处理括号序列

一个栈,遇到左括号压入栈,遇到右括号判断栈顶是否为左括号,如果是则弹出栈顶,否则不合法。

bool flag=1;
for(int i=0; i<s.size(); i++) {
if(s[i]=='(') st.push(s[i]);
else if(st.top()=='(') st.pop();
else flag=0;
}
if(st.size()) flag=0;
puts(flag?"YES":"NO");
return 0;

1.3 单调栈

单调队列平替。例如维护一个顶小的单调栈,插入 x 时先将 <x 的弹出,然后插入。常用于优化 dp。

2. 队列

2.1 队列的性质

先进先出。

2.2 单调队列

维护一个头小尾大的单调队列,插入 x 时从队末将 >x 的弹出,然后插入。常用于优化 dp。

int head=1,tail=0;
//in a[x]
while(head<=tail && a[q[tail]]>a[x]) tail--;
q[++tail]=x;
while(head<=tail && x-q[head]>=t/*不满足条件*/) head++;

3. 并查集

值得注意的是路径压缩会破坏树的形态。

struct easy_dsu {
int fa[maxn];
int find(int x) {
while(fa[x]^x) x=fa[x]=fa[fa[x]];
return x;
}
void init(int n) {
for(int i=1; i<=n; i++) fa[i]=i;
}
void merge(int x,int y) {
int rx=find(x),ry=find(y);
fa[rx]=ry;
}
bool query(int x,int y) {
return find(x)==find(y);
}
};
struct size_dsu {
int fa[maxn],sz[maxn];
int find(int x) {
while(fa[x]^x) x=fa[x];
return x;
}
void init(int n) {
for(int i=1; i<=n; i++) fa[i]=i,sz[i]=1;
}
void merge(int x,int y) {
int rx=find(x),ry=find(y);
sz[ry]+=rx;
fa[rx]=ry;
}
bool query(int x,int y) {
return find(x)==find(y);
}
};
struct dis_dsu {
int fa[maxn],dis[maxn];
int find(int x) {
if(fa[x]!=x) {
int y=find(fa[x]);
dis[x]+=dis[fa[x]];
fa[x]=y;
}
return fa[x];
}
void init(int n) {
for(int i=1; i<=n; i++) fa[i]=i,dis[i]=0;
}
void merge(int x,int y) {
int rx=find(x),ry=find(y);
fa[rx]=ry;
}
bool query(int x,int y) {
return find(x)==find(y);
}
};
struct merge_by_rank {
//不会破坏树的形态
int fa[maxn],rk[maxn];
int find(int x) {
while(fa[x]^x) x=fa[x];
return x;
}
void init(int n) {
for(int i=1; i<=n; i++) fa[i]=i,rk[i]=0;
}
void merge(int x,int y) {
int rx=find(x),ry=find(y);
if(rx^ry) {
if(rk[rx]<rk[ry]) fa[rx]=ry;
else if(rk[ry]<rk[rx]) fa[ry]=rx;
else fa[rx]=ry,rk[ry]++;
}
}
bool query(int x,int y) {
return find(x)==find(y);
}
};

4. hash 表

给一个数处理一个 hash 值,有奇妙的用处。

CF1746F

考虑如果一段区间合法,那么你对每个数值进行哈希,这段区间哈希值的和必定是 k 的倍数。注意到这只是充分条件,不能反推,所以多哈希几次就行。

ABC339F

对每个数hash一下,暴力匹配。

5. 链表

实现相邻访问 O(1),快速从头尾删除、插入,快速随机访问。

6. ST表

一个很像 dp 的数据结构,可以做到 O(nlogn)O(1) 维护区间最大值、最小值、gcd等可重复性的信息。

P3865 为例。

fi,j 表示从 i 开始 2j 个位置的最大值。

那么可以得出状态转移方程 fi,j=max(fi,j1,fi+2j1,j1)

那么可以 O(nlogn) 转移。

考虑查询:可以直接查询 [x,x+2k][y2k+1,y],其中 k=log2(yx+1)

最小值同理。

同样,我们也可以维护区间 gcd,因为 gcd 重复算肯定是可以的。P1890

本文作者:lgh_2009

本文链接:https://www.cnblogs.com/lgh-blog/p/18042777

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   lgh_2009  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起