BZOJ 4299 Codechef FRBSUM | 主席树

题目:BZOJ 4299 Codechef FRBSUM

  题目大意:

    

  对于一个可重集,如果前 i 个数能表示到 max,新来一个数 x:如果 x <= max + 1,则能表示到 max + x;如果 x > max + 1,则只能表示到 max。

  由此推出,若一个子集 S 能够表示到 max,则 max = sum{i} (i <= max + 1, i ∈ S)。

  如果想不明白,我们详细解释一番:

  一个子集能够表示到 max,则 max = 子集中小于等于 max + 1 的所有元素之和。根据上面粉色的定理,max 一定是由小于等于 max + 1 的元素加起来的;

  而对于大于 max + 1 的元素,它并不能使 max 的值发生改变,所以不进行求和。

也就是不断扩展max的值,直到小于等于max + 1的元素无法凑出max + 1,max即为答案。

举个栗子:

  集合 {1, 2, 4, 9}。max 初始值为 0。

  1. 集合中小于等于 max + 1 的数:1 >= max + 1。max = 1。

  2. 集合中小于等于 max + 1 的数:1 + 2 >= max + 1。max = 3。

  3. 集合中小于等于 max + 1 的数:1 + 2 + 4 >= max + 1。max = 7。

  4. 集合中小于等于 max + 1 的数:1 + 2 + 4 < max + 1。max + 1 即为最小的不能表示的数。

   用tree(i)表示前 i 个数的状态,结点储存某个数出现的次数。问题就转化成了在一段区间内,权值小于等于某个数的和。

  

posted @ 2018-02-07 16:36  Milky-Way  阅读(150)  评论(0编辑  收藏  举报