数据结构总结

这几天学了很多知识,但感觉像是囫囵吞枣,走马观花。还有许多只是没有消化。

首先是堆,这几天许了可并堆,只大略掌握了左偏堆的写法。
左偏堆比普通的堆多了一个dis键值,它要满足节点dis=右节点键值+1,左儿子节点dis >= 右儿子节点dis。然后它几个重要的操作有merge(合并),,,,,好像只有merge,还有就是insert和del吧但这些都是在merge的基础上。

这是bzoj1455的代码:

#include<cstdio>
#include<algorithm>
#define N 1000005
using namespace std;
int n,m,x,a,b,dead[N];
char s[2];
struct Tree{
    int val,dis,id;
    Tree *l,*r;
};
Tree pool[2*N],*root[N],*tail=pool;

inline int dis(Tree *t){return t==NULL?0:t->dis;}
inline void update(Tree *t){
    if(dis(t->l)<dis(t->r))
    swap(t->r,t->l);
    t->dis=dis(t->r)+1;
}
Tree *merge(Tree *a,Tree *b){
    if(b==NULL)return a;
    if(a==NULL)return b;
    if(a->val>b->val)//小根堆 
    swap(a,b);
    a->r=merge(a->r,b);
    update(a);
    return a;
}
inline Tree *del(Tree *t){return t==NULL?NULL:merge(t->l,t->r);}
Tree *newtree(int val){
    Tree *nd=++tail;
    nd->l=nd->r=NULL;
    nd->dis=1;
    nd->val=val;
    return nd;
}
inline Tree *insert(Tree *a,int val){return merge(a,newtree(val));}
int fa[N];
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int main(){
//  freopen("date.in","r",stdin);
//  freopen("my.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        root[i]=newtree(x);
        root[i]->id=i;
        fa[i]=i;
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%s",s);
        if(s[0]=='M'){
            scanf("%d%d",&a,&b);
            int x=find(a),y=find(b);
            if(dead[a]==-1||dead[b]==-1||x==y)continue;else fa[y]=x;
            root[x]=merge(root[x],root[y]);
        }
        else{
            scanf("%d",&a);
            int x=find(a);
            if(root[x]==NULL||dead[a]==-1){
                printf("0\n");continue;
            }
            if(root[x]!=NULL)dead[root[x]->id]=-1,printf("%d\n",root[x]->val),root[x]=del(root[x]);
        }
    }
    return 0;
}

还有就是单调栈,单调队列,这两个玩意我用的很少,就没有怎么做过这方面的题目,基本上没怎么了解过它们的性质和用法。
单调队列和单调栈基本上就是用来维护一组单调的队列,只不过是两个不同的维护方式,感觉我用单调队列只搞过dp优化- -、
在暑假15天这两个需要好好弄一弄。
这是这两个要刷的题目:bzoj1012,bzoj1047。

并查集也是一个大头,它有两个比较重要的优化,一个是按秩合并,一个是路径压缩。
路径压缩在有些题不能用,因为它会覆盖掉一些信息。
按秩合并的重要思想是存一个树的高度,每次把高度低的连向高的,如果高度一样才会把高度加1,这样每次生成的树会比较平衡,杜绝了出现一条链状的情形。

还有一个我现在基本还云里雾里的就是可持久化并查集,这玩意有空了在去弄它吧0 0。

dfs序和rmq st表就不用说了,最近听说了一个比较高端的东西叫什么括号序有空也要搞一搞。

常言道:LCT=树链剖分+splay 这俩玩意感觉都搞得差不多了,但就是有点看不懂LCT。

最近学习算法,总结了一下方法,就是先看算法目的和思想,在看题,结合题目是学习算法的重要思想,并且要学习黄学长的代码,实在太优美了,ORZ ORZ ORZ。

分块算法,还是搞搞莫队吧,现在大致会莫队了,但进阶版可修改莫队还云里雾里的。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值