现在的位置: 首页 > 综合 > 正文

Sicily 1088. Cows[树状数组]

2014年01月18日 ⁄ 综合 ⁄ 共 2083字 ⁄ 字号 评论关闭

这是我第一次接触树形数组,刚开始看题的首先想法,是O(n2)的朴素算法,但是看到n是105  就放弃了...最后实在想不到什么好的方法,上网一搜发现时树形数组,之前只是听说过,连它是做什么的都不知道...

然后花了一晚上去搜索属性数组的知识,发现了一片比较好理解的文章,转到了我这里,地址是http://blog.csdn.net/titikdhu/archive/2010/07/21/5751887.aspx

好了,转来说这道题吧~其实我感觉即使知道要用树形数组的话,具体的实现方法也不好想...他是先以结束位置ed为关键字进行升序排序,若结束位相同,则以起始位st为关键字进行降序排序。然后对所有的区间进行逆向遍历(即从最后一个开始,倒序)。最终想要达到的效果是,由于是逆向遍历,所以保证了cows[i+1].ed>=cows[i].ed,故要判断两头牛的强壮与否只需判断两者的st。其实这里引用了树状数组的数据结构和这种排序(也是种离散化)不无关系。

现假设有大小两个区间,且大区间的结束位大于等于小区间的结束位。我们先判断的是大区间,然后将该区间的起始位st之后的区间求和+1,即表示该区间上有一头牛,当有一个小区间存在,若小区间的st小于大区间的st,则表示两头牛是相交的无法判断谁强壮,而且这时对小区间st之前的位置进行求和由于大区间的st大于小区间st,故求和值肯定为0,表示没有比该校区间的牛更强壮的牛,符合假设;若小区间的大于等于大区间的st,即表示小区间完全包含在大区间中(这里先不考虑两区间完全相同的情况),这时对小区间起始位st之前进行求和,由于有大区间st的存在,所以求和为1,即表示有一头牛比当前小区间的牛强壮。类似的这是两个区间的比较,可以继续拿小区间和其他的大区间比较(当然是在大区间的结束位大于等于小区间的结束位的前提下),比较和这个类似。由于我们实现进行了排序,所以现在的序列历经符合了我们“大区间的结束位大于等于小区间的结束位”的要求,故可以直接像上面叙述的一样判断,不必要考虑很多,其实就是两两的比较,只不过那些大区间在小区间出现之前都已经标记好了,只需小区间对其起始位st之前进行求和,即判断有几个大区间包含他(即比他强壮)即可。

其实说了这么一大推,只是我这个不了解树状数组的新手初次接触时候的不明白,我发现网上的很多介绍树状数组的文章都比较抽象,上来就是二进制...对于新手来说一张图可能胜过十行解释,所以要是初次接触的话,我还是觉得上面那个链接的文章比较适合。

 

附上代码(sicily上居然进了这题的第一版~有些意料之外):

 

抱歉!评论已关闭.