Live2D

Solution Set -「OurOJ Contest #2587」浅写

A「OurOJ #47030」_

  Link & Submission & Tags:「A.DP-计数 DP」「A.数学-Stirling 数/反演」「B.Tricks」

  我们习惯于用组合数拆形如 lk 的贡献,可惜 O(nk2) 的复杂度不被允许。我们需要找到更优秀的贡献拆分方法。

  关于幂,可以想到 Stirling 反演。考虑

lk=i=0k{ki}li_,

其中 li_ 看上去并不好维护,但是它有一个很简单的组合意义:从走过的 l 条边里有序地选出 i 条的方案数。除一个 i!,那就是 (li),即无序地选出 i 条边的方案数。我们对这个计数问题暴力 DP,令 f(u,i) 表示从 1 走到 u,已经在路径上选了 i 条边的方案数。O(nk) 转移就行。

B「OurOJ #47031」__

  Link & Submission & Tag:「A.数据结构-树套树」

  “至少出现一次”,可以尝试直接不重不漏地进行加法贡献。那么当 u 的颜色变为 c 时,所有 u 的祖先中,子树内以前没有 c 颜色的结点都会受 u 贡献;当 u 的颜色从 c 改变时亦有类似讨论。用 set 维护一下每种颜色出现的 DFN,可以倍增求出最高的满足要求的 u 的祖先 v

  然后呢?BIT 套线段树差分维护“uv 的数量上每个点答案的 c 位置 ±1”,O((n+q)log2n),不卡常。

C「OurOJ #47031」___ *

  Link & Submission & Tags:「A.DP-状压/插头 DP」「C.性质/结论」

  条件的转化很关键,不要一味按照题目描述的顺序思考,例如本题,可以想想,如果先把所有权值随机出来,我们能得到多少种点分树?

  ——只有唯一一棵!每次分治区域内的最小值位置需保证唯一,这个点就是当前分治中心,依此递归构造,一种点权方案要不非法,要不只能由一种点分树生成。

  进一步,怎样才能保证最小值位置唯一?——对于任意两个权值相同的结点,它们的树上路径中必须存在权值更小的结点。可见这是合法的充要条件。

  接下来的求解就平凡了。令 f(u,S) 表示 u 子树内,能从对应点出发,仅经过权值不小于自己的结点,走到 u 以上的权值集合为 S,暴力转移可做到 O(n3k)

  然后,如你所见,极其卡常。给一些我加的优化叭。

  实现层面,不要用任何辅助数组。注意贡献形式是,当 ST=S 的最高 bit 不在 T 中时,f(u,S)×f(v,T)f(u,{xxhigh(S)(xSxT)})。从大到小枚举 S,同步在 f(v) 上滚类似后缀和的东西即可。

  卡常技巧:

  • 指针存一下二维状态的第一维,保证瓶颈处只有一维数组访问;

  • 虽然不知道效果明不明显,也不知道科不科学:DP 的第二维不要恰好开成 2k,这样很浪费 cache line;

  •   #pragma GCC optimize("Ofast")
      #pragma GCC target("avx, avx2, mmx, sse, sse2, sse3, sse4, ssse3")
    

  最后,值得一提的是,f 的转移可以表示为一定条件下的集合卷积,至少可以无脑优化至 O(nk32k),理论层面比较优秀,但是算出来巨大,标算没采用这种做法可以理解。另一方面,完整的贡献形式并不是位运算卷积,所以可能很难用类 FWT 的思路取得更好优化效果。

posted @   Rainybunny  阅读(87)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示