ACM训练周末总结—10月8日

来源:互联网 发布:php时时彩架设教程 编辑:程序博客网 时间:2024/06/05 06:29

       这个假期的训练虽然出了些问题,但收获还算不少。

       假期刚开始的时候因为说杭电系统关闭,所以我一直专心做vj上的题目,可能因为线段树不好的原因,十分不好做。第一个题就是珍珠项链题, 给一串数,找指定区间上有多少种数,首先,利用树状数组getsum(i),可以得知前i位数之前出现了几种不同的数,而getsum(r)-getsum(l-1)就找出了给区间范围有多少种不同的数,为了避免重复记录,利用一个数组记录该位置的数上一次出现的位置,按顺序操作将上一次位置-1,当前位置+1,因为每一个区间都是从前到后这么操作,所以将区间离线操作,按r排好一次做就行了。另外z国公主那道也是同样原理,只是要将给位置点上上次出现的位置删除,上次加入。总的来说这是一类离线操作的树状数组题,杭电专题上的也有重题,一样都是离线操作。

       另外J 题,给一串数列,1,将给定区间成一个数。2,将给定区间加一个数,3,查询区间和。这个题本身不难,我想的是用一个特殊的懒惰标记(结构体形式)(当然后来跳了好长时间,检查画了画树图忽然发现发现不行),直接暴力一点两个懒惰标记,更新到该点下放一层,正常做。一道水题浪费好长时间QvQ。

       还试着做了下H题,题目就是区间操作,数列中只有1和0,区间操作,给区间全变1,全变0,0和1互换,查询区间1的个数,和最长连续1,其实这就是一道大综合的题,既要有区间合并,区间更新,懒惰标记运用。这道题既要有懒惰标记标记区间是那种颜色(1或0),还是混色(-1),还要有区间合并的,因为存在0与1互换的操作,要有数组记录连续0和连续1的最长长度,操作时找到该区间进行两数组互换就行了。区间更新,当访问给区间是懒惰标记下放。 总的来说,很惭愧,这道01区间综合操作的题对我来说太难了点,还是线段树这块不行,很惭愧。

       vj上的题对我来说实在具有挑战性,之前太偷懒,导致现在QvQ。

       另外,做vj时还学习到一个有意思东西Zkw线段树,学习了一下发现zkw线段树的效率,代码长度,都要比线段树好很多,非常巧妙。zkw线段树是一棵完全二叉树(重点是完全,这是与普通二叉树不同的地方),线段树建树时是从完全二叉树最上层向下找,一直到底在向上返回,但是其实我们在知道存储序列长度时可以定位到最下一层新段树的位置。这时找到 最下一层第一个的位置,存入这个完全二叉树,在依次向上返回;for(int i=1;i<=M;i=i*2);这样就可以找到最底层 。因为是完全二叉树,所以单点更新时直接定位最底层往后数就可以了。其实不难发现zkw是一种自下而上的完全二叉树,因此操作只要走一遍就行,有时是会展现奇效。至于更多内容还是看这位大神的讲解吧https://zhuanlan.zhihu.com/p/29876526    

       其实及其最刺激的是昨天,咸姐让我看下第八题,结果我说的和她将题题目不是一道题,咸姐告诉我杭电题目能做了,只是入口不同了。我心里瞬间凉了一半,费老师发的网址我以为是给15级的,没留意下面夹着线段树专题。当天晚上就做好了通宵刷题的准备QAQ。不过说起来杭电专题的题目水起来感觉要容易了。不说了去水题了。