$100+30+47=177$。
给定 $n$ 个人和 $m$ 个工作,第 $i$ 个人有 $0\sim 2$ 个讨厌的工作,求每个人选一个工作、一个工作最多被一个人做,且没有人做自己讨厌的工作的方案数。
$n\le 17$,$m\le 10^6$。
考虑令 $g(S)$ 表示 $S$ 中的人都做讨厌的工作、$S$ 外的人都做喜欢的工作的方案数,转部分满足,设 $f(S)$ 表示 $S$ 中的人一定做讨厌的工作的方案数,其余人随意。设 $h(S)$ 表示 $S$ 中的人做讨厌的工作的情况下,对这 $S$ 个人分配工作的方案数,那么有 $$ f(S)=h(S)(m-|S|)^{\underline{n-|S|}} $$ 因为 $$ f(S)=\sum_{T\subseteq S}g(T) $$ 所以 $$ g(S)=\sum_{T\subseteq S}(-1)^{|T|-|S|}f(T) $$ 答案显然是 $g(\varnothing)$,于是 $$ \begin{aligned}g(\varnothing)&=\sum_{T}(-1)^{|T|}h(T)(m-|T|)^{\underline{n-|T|}}\&=\sum_{i=0}^n(-1)^i(m-i)^{\underline{n-i}}\sum_{|T|=i}h(T)\end{aligned} $$ 这个时候就不要往下推了!注意到 $h(T)$ 这个东西可以直接暴搜枚举每个人做不做讨厌的事情、做哪件讨厌的事情,假设某次暴搜出一个大小为 $siz$ 的合法情况,直接贡献到 $\sum_{|T|=siz}h(T)$ 里即可。时间复杂度 $O(3^n+n)$。
给定一个长度为 $n$ 的序列 $a$,$Q$ 次询问每次给定一个区间 $[l,r]$,求将 $a$ 中 $[l,r]$ 的部分从小到大排序后,区间中相邻元素原本在 $a$ 中的编号的差的绝对值之和。不强制在线。
$n,Q\le 5\times 10^5$,$a$ 中元素两两不同,时限 8s。
考虑莫队,一个比较直接的想法是用平衡树维护当前区间内元素排序后的结构,增删贡献是简单的,时间复杂度 $O(n\log n\sqrt n)$。如果不考虑添加元素,只有删除,那么可以用一个双向链表来快速查询一个被删除的元素的前驱后继,所以把莫队换成回滚莫队即可。时间复杂度 $O(n\sqrt n)$。
不知道暴力莫队哪个地方写错了,导致好像复杂度有些问题,可能是 set 访问地址的问题?
给定一棵 $n$ 个点树,第 $i$ 个点有两个参数 $(t_i,w_i)$;你需要给每条边 $(u,v)$ 定一个边权 $w(u,v)$,然后对于每个点 $u$,如果 $u$ 到根的路径中的边权最小值恰好等于 $t_u$ 那么你可以获得 $w_u$ 的收益。求最大收益。
$n\le 10^6$。
考虑树形 dp,令 $f(u,t)$ 表示 $u$ 与其父亲的边边权设为 $t$ 得到的答案。那么有转移: $$ f(u,t)=[t=t_u]w_u+\sum_{v\in\mathrm{son}u}\max{t’\le t}f(v,t’) $$ 令 $g(v,t)=\max_{t’\le t}f(v,t)$ 即每个点的 dp 数组的前缀 $\max$,那么转移变成 $$ f(u,t)=[t=t_u]w_u+\sum_{v\in\mathrm{son}_u}g(v,t) $$ 可以发现这相当于先将子树的 $g$ 数组相加,然后再做一个单点加,最后求一遍前缀 $\max$ 得到 $g(u,t)$。考虑每一个本质不同的前缀 $\max$ 其实只对应一个 $t_u$ 的位置,因此可以考虑线段树合并。
可以发现若干个单调不降的数组加起来结果仍然单调不降,因此我们只需考虑在 $t_u$ 上加上 $w_u$ 对 $g$ 的影响。这相当于一个区间推平,右端点是第一个大于 $w_u+f(u,t_u)$ 的位置。线段树二分即可。
这么构式的方法还真让我过了