NOIP数据结构概论

先推荐一下codevs网站,网址 http://www.codevs.cn,之前noip大多数都是在这里面做题的

codeforces有空的,也可以尝试一下,不过貌似都是英文的  http://codeforces.com

下面进入正题,NOIP所需要掌握的数据结构,下面的难度不一,但是都需要掌握,线段树以及树状数组会单独列出

  • 线段树
    1. 线段树,是一个完全二叉树。支持区间修改,区间查询,单点修改,单点查询,多用于一段连续序列进行多次查询,多次修改。但是,要注意连续二字。必须是一串数字,而不能是断开的。除此,线段树的空间是原数组的4倍。
    2. 单点修改,区间查询:(修改)分治思想分到l==r开始往上更新,只往更新后答案改变的那一边更新。
    3. 区间修改,区间查询:注意pushdown操作,若当前区间被需要修改的区间的区间完全覆盖,那么标记好,并把当前线段树节点赋好值。查询时需要下放标记
  • 树状数组
  1. 树状数组,与线段树作用差不多,相比之下要更好实现,而且常数要更小些。不过要注意树状数组的数组大小至少是原数组的2倍。对于实现单点修改,区间查询是很容易的,但如果要实现区间修改,区间查询,那么就要运用公式了。
  2. 区间树状数组:

  第一步 : 输入 a[i] ,新起另一个数组 d[i]存 a[i]-a[i-1] 。

  第二步:以 d[i] 为基础构造c[i] 树状数组,与普通树状数组的第一步一样。

  第三步:当进行区间修改时,设输入区间为[l,r], 增加量为sd[l]=d[l]+s;

  D[r+1]=d[r]-s;

 第四步:当求单点值时, a[i]=d[1]+d[2]+…..+d[i];

      第五步:当求区间值时,第三步时对所有改变的 d[i] 依照普通树状数组改变 c[i]的值,最后依照普通树状数组,c[r]-c[l] 及可求值,我对普通树状数组并不熟,尤其是第二步和第三步

  1.  树状数组修改一个结果后,若编号为 x ,则x+x&(-x) 及其所求的父亲节点

x-x&(-x) 及其所求的区间和

(r-l+1)*(d[1]+…+d[l-1])+(r+1)(d[l]+…+d[r])-(l*d[l]+(l+1)*d[l+1]+…r*d[r])

  • ST表
  1. 时间复杂度:建表O(nlogn),查询O(1)。
  2. st表目前最好用的地方就是求rmq,虽然线段数也可以做到时间复杂度和st表差不太多,但对于多询问的话还是用st表来解题。主要分为两个部分: 

预处理:dp思想倍增思想,用f[i][j]表示在(i,i+(1<<j)-1)这段区间的最值,所以由此可见f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

查询:dp思想,对于区间[l,r]的最值,由于根据f[i][j],先找出最大的k,满足2^k<=r-l+1,为啥是这样呢,根据先前f[i][j]的定义,k就是f数组的第二维,也就是倍增的次数,那么f[l][k]就表示了在所求区间内的(l,l+(1<<k)-1)这段区间。可以看出(l+(1<<k)-1)明显比r小,所以所求的最值就是max(f[l][k],f[r-(1<<k)+1][k]), f[r-(1<<k)+1][k]的意思是指区间(r-(1<<k)+1,r),从此可以看出两个区间虽有少量重复,但将[l,r]这段区间完全覆盖了。(问题:空间复杂度太大,如何优化空间复杂度)解:其实判断错误虽为二维,但k表示(1<<k),一般不会大于20,所以还是很划算的。

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。很简单自己用系统栈或是用数组模拟即可。

 

 

  • 优先队列

优先队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。优先队列其实就是堆,考试中一般用的是系统堆。

bool operator<const(node &a)const{ return a.dis<dis;};

priority_queue<node> q;

小根堆

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值