一棵树
题意
题解
$k=0$ 不难,略。
一个显然的想法是枚举断掉的边,然后看每条边的贡献。
贡献分为两类,一类是新加的边的块间贡献:
这个不难算,另外一类是原先的边的块内贡献。
不妨设虚线边断开,实线边把一个连通块分为大小为 $a,b$ 的两块,则这条实线边的贡献是上面的式子。
于是在枚举了虚线边之后,分子树内,祖先,既非子树也非祖先三种情况讨论,不妨设 a 是虚线边较深的端点,b 是实线边较深的端点:
可以发现,三个贡献的式子后两项都只和 a 有关,前两项都可以展开成和 b 有关的二次多项式,因此只需要维护下子树内,祖先上的 sz 的和,sz 的平方之和即可快速计算。
代金券题解
题意
与值域无关做法——贪心
做如下的一个转化,可以看成有三种操作:
- 支付 1 个代金券
- 支付 1 块钱,不获得代金券
- 支付 c 块钱,获得一个代金券
记 $X_i$ 表示第 $i$ 道菜进行操作 1 的次数,$Y_i$ 表示进行操作 3 的次数。
用最少的钱等价于用最多的代金券。因此最优解有如下性质:
- 有代金券时不会进行操作 2(代金券越靠前使用越好,否则后面可能没机会用了)
- 3 操作必定越靠前越好(感性理解是提前获得了代金券,使用的机会更多了):
下面是一种调整方法:
$$ Y_i=\lfloor \frac{A_i}c\rfloor, X_i=\min(R_{i-1},A_i\bmod c), R_i=R_{i-1}+Y_i-X_i $$
但是,我们知道,满足这个贪心策略的仅仅是一个前缀,那么这个贪心策略进行到哪里呢?
记 $S_i=\sum_{j\ge i} A_j$,表示 $i$ 后面菜的价值之和。
我们发现:当 $R_i\ge S_{i+1}$ 的时候,就没有必要再进行操作 3 了,因为此时 $i$ 后面后面都可以全用代金券买了。
同时,不难发现满足 $R_i\ge S_{i+1}$ 的 $i$ 是一个后缀。而我们必然在满足这一个条件的第一个 $i$ 就结束了贪心。所以,如果我们能快速判断某个位置是否符合上述条件,我们就能二分求出 $i$ 的位置。
此时我们可能还有一些代金券没有用上,所以我们还需要重新规划第 $i$ 道菜的策略。 首先:
- 如果 $R_{i-1}
- 如果 $R_{i-1}>S_{i+1}$,那么就可以把多出来的 $R_{i-1}-S_{i+1}$ 张券在第 $i$ 道菜上用掉。
此时,$i$ 后面花的 $S_{i+1}$ 个券分为两类:第 1 类来自于 $R_{i-1}$,第 2 类来自于 ${Y_i}$。第 1 类券我们可以把它移到第 $i$ 道菜上用,但是第 2 类不可以。
思考一下,还什么方法可能用更多的券?只能增大 $Y_i$,产生一个 2 类券,代替 $S_{i+1}$ 中某个 1 类券的位置,然后再把这个 1 类券移到第 $i$ 道菜上使用。
不妨设 $S_{i+1}$ 中有 $C$ 个 1 类券,第 $i$ 道菜还剩下 $Z$ 块钱没付。那么我们最多能进行 $\min(C,\lfloor \frac Z{c+1}\rfloor)$ 次上述操作。
复杂度 $O(qn)$,拼几个特殊性质,就能喜提 50 左右的好成绩。
上数据结构
难点在于在修改过程中维护 $R_i$,当时考场上就是没想出来这个,就寄了。官方题解中没太搞懂,网上找到一种硬维护的做法。
线段树节点上记三个数 $div,mod,use$ 分别表示区间内所有数除 $c$ 下取整之和(也就是能产生的代金券个数),模 $c$ 之和(也就是最多能使用的代金券个数),以及在初始没有代金券的情况下用贪心策略,会用掉几个代金券。
然后你神奇的发现,这个东西是可以合并的:
|
|
前两项显然,解释下第三项咋合并的,x.use + y.use
也是显然的,而 min(y.mod - y.use, x.div - x.use)
表示左边一半用剩下的代金券数量,和右边一半最多能使用的代金券个数取 min。
于是线段树二分即可。
|
|