[考试]20151017数据结构

1、前言

  表示今天学的东西还是挺多的,数据结构一直以来内容就多。第四题比以前做过的一道题还水一些,结果没有写出来。

 

2、R R的烦恼

大概题意:给出一个长度为n的数列,共t个操作,每次可以将一段区间增加x,也可以寻找数列中最左端和最右端的k,输出距离。

总结:考试的时候并没有写出来,只能想到线段树,但是显然维护起来是要死的。开始只听说过分块,但是并没有去试过,可能也是因为用的不是很多。这道题的话用分块是很好做的,时限是3s,是可以过的。

题解:

  分块。由于我们需要寻找最左端的某个值和最右端的某个值,线段树若要维护某个值的位置,太麻烦了。首先我们想一下暴力的写法。区间修改,直接for循环;寻找k,从左和从右进行两次for循环。如何加快速度?我们考虑将这个数列均匀的分成若干块,对每一块进行处理。

  类似于线段树,我们在某些情况下,为了降低复杂度,会给一些目前暂时不需要进行修改或询问操作的区间先做一个标记,表示这一段将要加上某个数。假设当前给[l,r]增加x,可能横跨多个块,对于中间的块直接上标记;对于左右侧没有全覆盖的块,直接进行暴力加减。

  询问的过程看起来似乎复杂度就比较高了,其实不然。我们每次对某个块进行修改之后,可以将其从小到大(反之亦然)进行排序,那么在每个块中询问某个数的时候,可以直接二分答案。

  这一切貌似并不是很高端的东西,但是它的最低复杂度远低于暴力枚举。为何称之为最低?注意到,分块的大小我们并没有定义。而从上述描述中也可以看出来,块的大小似乎并不影响程序的正确性,故我们只需要找到一个最合适的大小,使复杂度最低。一般情况下,大小选取√n,也可以自己去定。平均复杂度为O(t * (√n log √n),3s是可以过的。

 

3、Card 神秘卡片

略。

 

4、Captain 分队

大概题意:给出n个点,每个点存在两个值a[i],b[i]。共t次询问,每次询问给定两个数,要求找出包括这两个数的一个数集合,满足:集合中a值最高者i,b[i]与其他数的b的绝对值相差小于等于k。

题解:从50分做法想起。由于分组的规则只和a值最高者有关,那么我们先预处理出每一个数作为最高者的情况下,队伍中最多可以存在多少个人。询问过程中,每次要找到一个a值大于等于两者较高者的点,同时b值满足条件,选择队伍中人最多的情况即可。这样,时间复杂度为O(n ^ 2 + t * n),显然是过不了的。

如何将一个n优化掉?第一步,预处理过程中,因为和位置无关,则可以排序之后用树状数组维护。第二步询问,我们可以离线进行回答。将每次的询问按要求的最小a值排序,将每一个人按a排序后加入,依次回答询问。这样可以用线段树来维护最大人数了,时间复杂度O(n log n + t * log n)。

 

5、qtree xdz的难题

大概题意:给出一棵根节点为1的树,维护下列几个操作——将根换为x,将一个节点权值改为v,询问一个子树中所有节点的最小值。

题解:

  BZOJ上遥远的国度的简化版,不要用树链剖分维护,直接线段树。不要看到换根就自动脑补动态树云云了,这道题只需要考虑询问子树的根节点与整棵树当前的根节点的关系即可。

  用线段树维护,加上换根操作,记当前的根为root,询问子树的根为x,如果root不在x的子树里,仍然维护原来的就行;否则如图所示(显然不是我画的。。。),除了红色部分以外,以x为根节点的子树就是所求部分,也就是x最近的属于root到1路径上的点,在DFS序上是连续的一段,故直接用线段树即可。

posted @ 2015-10-18 22:57  jinkun113  阅读(206)  评论(0编辑  收藏  举报