zoukankan      html  css  js  c++  java
  • noi前第九场 题解

    A. s1mple

    可以发现 0/1 这个限制类似于求路径数,使得路径经过的边权恰好合法。
    显然可以用容斥来求,这样可以将问题转化为钦定其中若干条边权为 (1),其他边权任意的路径数。
    这样做有一个好处,原来问题中的 (2^{n-1}) 的集合可以缩减状态数。
    对于钦定之后的若干条 (1) 边组成的链,可以直接视为无序的。
    也就是说,可以直接对 (n) 进行整数划分,然后求这种整数划分的方案数,即可放到对应的集合状态上。
    对于求方案数,只要首先 (dp) 出一个集合组成一条链的方案数。
    对于每种整数划分,用类似不交并卷积的思想卷在一起即可。
    注意到这里对于每种整数划分,所有项加和起来才恰好为 (n),所以不需要用不交并卷积的占位多项式。
    注意到只需要 (ifwt) 单点插值,所以可以在整数划分的同时进行卷积,优化一下复杂度。
     

    B. s2mple

    可以发现这样一个事情:
    原问题等价于对于 (s[l,r]) 的两边添加字符,能形成的满足前面或者后面添加的字符本质不同的方案数之和。
    (SAM) 上做这道题,考虑首先找到 (s[l,r]) 对应的节点,对于在前面添加字符的限制,只要对子树求和。
    对于在后面添加字符的限制,其实只需要在树上用一个 (set) 启发式合并 (endpos),并用 后缀数组/另一个后缀自动机 统计本质不同的前缀个数即可。
    另外一个做法是直接在 (DAG)(dp) 求出这个点出发的本质不同的路径数。
    注意对于子树中的节点 (x) 可以直接统计 ((len_x - len_{fail_x})*dp_x)
    而对于当前节点,有一个长度限制,所以只能统计 ((len_x - (r-l+1) +1)*dp_x)
     

    C. s3mple

    容易发现可以把原问题放到笛卡尔树上,然后可以随便写个 (dp)
    然后可以发现状态里的 (l,r) 是没用的,所以直接记录区间长度、需要统计的贡献数。
    观察贡献的式子可以猜测贡献不会很大,所以可以另外写个 (dp),来处理出每个区间长度的贡献上界。
    可以发现这个玩意大概是 (n log) 级别的,在 (n=200) 的时候达到 (735)
    暴力去做 (dp),加个取模次数优化、循环展开、卡卡上下界就可以过掉这道题了。
    正解的做法是这样的,题中的 (P) 为一个大质数。
    最终的多项式是一个不超过 (735) 次的多项式。
    所以可以在点值意义下做多项式卷积,对于每次询问暴力插值得到系数就好了。

  • 相关阅读:
    SVN 的基本用法
    Git的基本用法
    一般情况下设计应遵循的原则
    设置默认以管理员运行的WinForm
    为 dll (类库) 解决方案添加测试项目
    C# WinForms跨线程更新 UI
    Android 创建 SO 文件
    SQL之case when then用法
    SQL LIKE 通配符随笔
    document.all.item作用
  • 原文地址:https://www.cnblogs.com/skyh/p/13357122.html
Copyright © 2011-2022 走看看