在病房里日题真是一种独特的体验……
首先考虑求第一问,我们先把所有元素排序,我们用优先队列维护选数的集合,对每个集合维护集合里的元素的和v和最后一个元素(即最大的元素)lst,初始的时候我们把只包含最小元素的集合推入队列,那么我们取出一个队头元素之后,如果队头的lst不是最大的元素,我们只需要再向队列里推入当前集合插入lst+1后的集合以及先删除lst再插入lst+1的集合。如果lst是最大元素,那么什么都不需要做
然后考虑求第二问,记录一下前k小里有几个和为答案的,设有x个,然后我们爆搜字典序第x小的和为答案的集合,我们用线段树维护区间最小值,然后每次在线段树上查编号最小的小于等于剩余的和的数,选这个数,搜下去
证明还是比较显然的,虽然我写了这么长
第一问的正确性证明:
首先这种方法能不重不漏第构造出所有子集
用归纳法,假设能不重复地构造出前i-1个数的所有子集,那么这时我们就相当于得到了前i个数的所有保有第i个数不选的子集ÿ