codeforces 739B B. Alyona and a tree

这个题目想了好久都没有想出好的方法,最终看了别人的思路解决的。写一篇博客纪念一下做这个题的想法和学到的一些新东西。读这个题的时候以为会是dp,仔细想了想,又不太符合dp的特征。然后,就按照数据结构的想法思考,想了好久,还是没什么思路,而且用队列,从叶子节点模拟了一发,以为可以过。提交的时候才想起来,肯定会TLE呀,结果果断TLE,想想也是醉了。最后想着想着,觉得时间复杂度怎么也应该时n*lgn才能过。于是,开始思考,如何能在lg(n)的时间复杂度内,解决一个节点的对所有节点的贡献。于是,想利用前缀和,看一下能不能二分,求出范围。这样,又有新的问题,从树根开始求前缀和的话,并不难。但是,自己怎么想都是应该求的是子节点到父节点的前缀和;第二个问题是即使求出了前缀和,找出了节点所影响的范围,但是怎么去更新这个范围尼。直接更新的话,不还是会超时。最后,选者了放弃。看了别人的想法。真是感慨自己的智商呀。 对于第一个问题:将dist(v,  u ) <= a[u]可以看成是dep[u](前缀和) - dep[v] <= a[u],可以转化为 dep[u]-a[u] <= dep[v];这样就可以二分找v的范围了。对于第二个问题:其实我们没有必要去一个一个的更新范围内的值,只需要定义前缀即可,若当前节点的值为1,则表示当前节点到树根的路径上每个节点均加1,那么对于要更新一个范围,只需要在尾部的位置加1,首部之前的位置减1即可,然后dfs求结果。最后,注意要用__int64。代码如下:

<

你可能感兴趣的:(dfs,codeforces,codeforces,B.,Alyona,and,a,tree,数据结构)