做题笔记3

\(\text{Update On} \;\;20261009\)

\(\text{Update On} \;\;20261020\)


\(\text{P11746}\)

分数和等于 \(n + m\),有因为要求自己是奇数, \(\text{AI}\) 是偶数,所以 \(n + m\) 必须是奇数,否则没有方案满足条件

所以只要 \(\text{AI}\) 是偶数就可以满足条件

正难则反,用总方案数减去整行整列完全相同的为奇数的方案数
设 \(S_奇\) 表示颜色完全相同的行列数为奇数的方案数


容斥,设 \(F_{i,j}\) 表示选择了 \(i\) 行, \(j\)列,强制满足这 \(i\) 行 \(j\) 列颜色相同,余下的随便填的方案数

分为三种情况

  • \(i > 0, j = 0\)
    \(F_{i, 0}=\binom{n}{i} \; 2^{i} \; 2^{(n-i) m}\)

    • \(\binom{n}{i} \to\) 选 \(i\) 行
    • \(2^i \to\) \(i\) 行颜色相同但是每一行都有两种颜色可以选择
    • \(2^{(n-i)m} \to\) 剩余的所有格子都可以任意选择颜色
  • \(i = 0, j > 0\)
    \(F_{0, j}=\binom{m}{j} \; 2^{j} \; 2^{(m-j) n}\)

  • \(i > 0, j > 0\)
    \(F_{i,j}=\binom{n}{i} \; \binom{m}{j} \; 2 \times 2^{(n-i)(m-j)}\)

    • 注意因为选出的行和列有交点所以行和列整体一定同色,只有全黑,全白两种

容斥求和计算 \(S_奇\)

\[S_奇 = \sum_{i=0}^n\sum_{j=0}^m (-2)^{i+j-1} F_{i,j} \]

容斥系数为 \(c_{i+j}=(-2)^{i+j-1}\)

这个容斥系数可以让在选出奇数个行列是贡献1,偶数贡献0

严格推导
定义 \(G(k)=\sum_{t=0}^k \binom{k}{t}c_t\),其中\(c_0 = 0\)
目标是找到合适的 \(c\) 使得

\[G(k)=\left\{\begin{matrix} 1, k为奇数 \\ 0, k为偶数 \end{matrix}\right. \]

二项式反演得到容斥系数是 \((-2)^{i+j-1}\)


行列都算的优化:二项式定理把和\(i\)有关的都提出去,内层换元用二项式定理消去一个求和公式,可以把复杂度降下来


最终答案 \(ans = 2^{nm} - S_{奇}\)

\(\text{P3813}\)

只考虑一个限制的情况下,发现方案数是不再矩阵的数上限是 \(m\),矩阵中有一个最大值是 \(v\),
发现要求 \(\leq v\) 的方案数很好求也就是\(v^{siz}\) 所以容斥,要求至少一个是 \(v\),就用 \(v_{siz}-(v-1)^{siz}\),任意 \(-\) 没有\(v\) 的方案数


那么扩展到多个矩阵,每一个格子都有一个上限,枚举 \(mask\),\(mask_i\) 表示第 \(i\) 个子矩阵的限制是\(v\) 还是 \(v-1\),然后用上限累乘,没有限制就是 \(m\),得到方案数。

由于格子大小很大直接做超时,发现一定会有一坨一坨的上限相同,于是离散化把矩阵左上角和右下角加入

\(\text{P2768}\)

\[ans = \sum_{L=0}^{N}\sum_{i=0}^K (-1)^{K-i}\times \binom{K}{i} \times i^L \]

\[=\sum_{i=0}^K(-1)(K-i)\times \binom{K}{i}\sum_{L=0}^N i^L \]

内层求和用等比数列求和公式优化即可

\(\text{P5628}\)

边权转点权然后简单容斥

\(\text{P15578}\)

推一下式子计算每一个排列成为树的概率,然后发现这个 \(siz\) 再从根到儿子的过程容易用换根 \(dp\) 求出

\(\text{P1269}\)

树形 \(dp\)
\(g_i\) 表示 \(i\) 最少需要的信号强度
\(f_i\) 表示 \(i\) 子数内最少需要增强个数
\(g\) 的转移从儿子取最大值
\(f\) 的转移累加
然后如果这个点已经\(g_i\) 加上父亲边权超限制,就在这里再放一个增强

\(\text{P3036}\)

最短路表示到一行或一列的最少距离,然后一个反射器相当与联通了一行和一列,然后距离是 1,
这里需要注意的是起点能到的行和列 \(dis\) 初始 -1 ,而最终答案是终点行和列的距离最小值,因为只要能到终点的行或列就能到终点

\(\text{P1402}\)

最大流,建图方式:

  • 源点向左右房间连容量1边
  • 房间向牛入连1边
  • 牛入向牛出连1边
  • 牛出向菜连1边
  • 菜向汇点连1边

这样可以保证每一个房间最多匹配一个牛,菜最多匹配一个牛,然后因为牛入牛出的限制,每一个牛有最多贡献一个匹配,然后一个匹配成功必然会经过房间牛菜,把这个牛给匹配完

\(\text{P3320}\)

走完一堆点的路径肯定是按照他们的 \(dfn\) 序走一遍
所以用一个 \(set\) 维护每一个点加入和删除时候的前缀和后缀,
每一次加入删除更新相邻两个点的贡献,这个距离提前预处理就可以了

\(\text{P7518}\)

一次查询的两个点之间的路径可以拆分成先上升到lca,再下降

『上升』:这个倍增预处理,每一个点采集到他之后的2的次幂的颜色上升到了哪里然后倍增的时候只要这个上升之后的深度不超过lca 就继续上升,
可以算出从\(u\)到\(lca\)这条路径上采集到了哪一个颜色

『下降』:直接倍增算的话,并不知道你从\(lca\) 到 \(v\) 收集了多少

因为你这里肯定是从 \(v\) 到 \(lca\) 向上考虑,这个路径是唯一的,

直接从\(lca\)向下的话你不知道会往什么方向走

然后发现这个答案具有单调性!可以二分从 \(lca\) 到 \(v\) 最终采集到了哪一个颜色

然后用从 \(u\) 到 \(lca\) 类似的方法从 \(v\) 上升检查是否满足条件

如果从 \(v\) 上升上来没有超过\(lca\) 这个二分的答案就合法,这里唯一不同的是从v往回的颜色是从大到小倒着收集的

\(\text{P5665}\)

因为 \(a^2+b^2<(a+b)^2\)
所以我们会在满足每段和单调不降的情况下尽可能的多划分段

\(n^2\)做法

记录\(f_i\)表示以 \(i\) 为结尾的段的最小代价
然后再记录一个 \(lst_i\) 表示 \(f_i\) 的转移是从 \(lst_i\) 来的
转移:\(f_{i}=min(f_{i},f_{j}+(s_i-s_j)^2)\) 满足 \(s_i-s_j\ge s_j-s_{lst_j}\)

单调队列优化

记 \(lst_j = k\)
那么 \(i\) 能转移的 \(j\) 需要满足

\[s_i-s_j \ge s_j - s_k \]

\[s_i \ge s_j - 2s_k \]

又因为只要能划分就尽可能的划分所以用单调队列,维护 \(calc(i)\) ,\(calc(i)=s_i - 2s_{lst_i}\) 单调不增,因为越是后来的 \(i\) 它的 \(calc(i)\) 越小,那它能转移得到的就越多,并且从 \(i\) 划分得到的段会比前面的点划分得到的这个当前段更短

然后开一个 \(int128\) 就过了

\(\text{P3628}\)

\(f_i\) 表示以 \(i\) 结尾的一队前 \(i\) 队最大战斗力和

\[f_i=max_{j\in[0,i-1]} f_j+A(s_i-s_j)^2+B(s_i-s_j)+C \]

\[f_i=max_{j\in[0,i-1]} f_j+As_i^2+As_j^2+2As_is_j+Bs_i-Bs_j+C \]

\[f_i-C-As_i^2-Bs_i=f_j+As_j^2-Bs_j+2As_is_j \]

这样写成直线解析式用李超树或者斜率优化就过了

\(\text{P3480}\)

差分 \(d_i=a_i-a_{i-1}\)
那么一次取石子相当于再\(d_i\)去了若干石子并把等量的石子加入到\(d_{i+1}\)
这是阶梯\(-nim\),然后结论是距离地面奇数层的石子阶梯的普通\(nim\),注意这里

是距离地面,并不是所有阶梯 \(nim\) 取石子都是直接找奇数

『地面』是指再某一级阶梯挪动的石子不会再向下传递而是离开游戏

这个题目中的『地面』显然是 \(n\) 所以答案是与 \(n\) 就就性相同的石子阶梯

\(\text{P4103}\)

虚数练习题
这个再相当那关于在虚数上查找所有点的距离和,距离最远的关键点的距离,距离最近的两个关键点的距离

直接建虚树然后虚树的树上边权等于原树上两个点之间的距离

然后第一问计算每一条边的点的数量,累加边权乘以这条边的经过次数
第二问和第三问用类似计算树的直径的方法

注意这里有一个误区
第三问求两个关键点的距离最小值并不能能直接找虚树上的最小边权因为可能链接的两个点并不是关键点

\(\text{P2597}\)

简单版支配树(这题是支配树最早被发明的例题)
建一颗支配树
如果 i 的食物有 \(p1,p2,...,p_k\) 那么 \(i\) 会灭绝当且仅当支配树上的 \(lca(p1,p2,...,p_k)\) 灭绝

这里用拓扑一边建树一边拓扑注意这两个过程是同时进行的,也就是走到一个点 \(u\) 的时候它再支配树上的父亲方向的边都已经连出来了,然后用 \(u\) 去找依赖它为食物的点,如果 \(v\) 还没有连边那么就 \(fa_v=u\),不然 \(fa_v=lca(fa_v,u)\)
初始的时候所有 \(fa\) 都是 \(-1\) 然后从 0 开始作为支配树的根拓扑

求答案就是再支配树上 \(siz_u - 1\)

\(\text{P7737}\)

首先强连通分量缩点把环给干掉
然后观察题目给的这个性质:
若 \(x\) 可达 \(z\), 且 \(y\) 可达 \(z\),那么有 \(x\) 可达 \(y\) 或者 \(y\) 可达 \(x\)
可以发现再这个性质下,这张缩完点之后的图的拓扑序是唯一的

因为如果有多个点可以到达 \(u\) 那么这些点之间就会互相有限制,也就是不会存在先走完一边再走另一边到 \(u\) 然后反过来还有多种情况的时候
所以拓扑序是唯一的

那么拓扑的时候找到每一个节点的唯一父亲(释放这个点的点)建成一棵树,那么从树根开始可以发现原图上互相到达的关系不变

然后考虑这 \(k\) 条边对可达性的影响(我们这棵树只能从根往叶子走)

当然可以大力分讨,更好的方法是虚数,可以经过的点就是满足 \(s\) 可以到达的集合包含 \(u\) 并且 \(t\) 可以到达的集合包含 \(u\)

具体实现的时候先把 \(k\) 条边的端点和 \(s,t\) 加入关键点,建虚树的时候虚树上的点权就是这个关键点所在强联通分量的点数
边权是原树上点强联通分量的点数和

然后建正图找 \(s\) 可达点,建反图找可达 \(t\) 的点
找哪些边可能经过就是枚举关键点和它的出边如果两个点都在路径上就加上边权

\(\text{P6821}\)

先选择把所有相邻正数段和负数段合并
如果正数段总数不超过 \(k\) 那么直接输出答案

所以选择的正数段选多了,所以要退还一些正数段或者把相邻两个正数段选择合并到一起,也就是把中间的负数段也选择上

直接反悔贪心

选完了之后这个反悔的权值变成相邻的加上自己的一起取反,因为如果这是一个正数,这就表示把它和周围的两个负数段一起选回去,如果这是一个负数

\(\text{P4101}\)

结论最终的局面一定会变成
\(m,m,...,r\)
\(r = n \mod m\)
也就是最终的局面会变成 \(\left\lfloor \frac{n}{m} \right \rfloor\) 堆 \(m\) ,和一堆不到 \(m\)
并且不管是先手还是后手都能再对方不配合的情况下达到这个局面

证明:
游戏中会一直维持着这样一种状态:现在有若干堆 \(m\) ,若干堆 \(1\) 以及一个特殊堆大小再1到m之间

如果对手合并两个1那么可以将这个 2合并到特殊堆,然后依然维持这个局面
如果特殊堆大小是 \(m-1\) 无法加入这个2那么将一个1加入到特殊堆让特殊堆变成m,2变成新的特殊堆

这个结论有什么用?
因为最终剩余了 \(\left\lceil \frac{n}{m} \right\rceil\) 堆
而初始 \(n\) 堆并且每一次合并恰好减少一个堆,所以总操作次数 \(n - \left\lceil \frac{n}{m} \right\rceil\)
如果这是一个奇数说明先手掌控了局面再打成一推 \(m\) 和 \(r\) 之后是由后首合并,后手无法行动故先手胜利

否则就是后首胜利

\(\text{P3999}\)

装压从某一个状态合并直到稳定之后的状态和得分,然后六进制装压每一个位置的等级,然后再设一位表示仓库的状态
根据定义简单转移即可

\(\text{P7962}\)

可以发现一次操作就是交换相邻的差分数组
记 \(d_i=a_i-a_{i-1}\)
然后有一个性质,最优的差分数组的排列方式一定是先降后升的,感性理解是为了让尽量多的数的值聚集到一坨

于是可以按照 \(d_i\) 从小到大的排序,然后对于依次考虑每一个 \(d_i\) 是插在最左边还是插在最右边

首先答案形式是

\[ans=n\times \sum_{i=1}^n a_i^2 - (\sum_{i=1}^n a_i)^2 \]

设 \(f_{i,j}\) 表示和当前 \(a_i\) 和为j的最小的平方和
插入到最左边,相当与给所有后面的 \(a_i\) 加上 \(d_i\)

\[\sum_{j=1}^i(a_j+d_i)^2 \]

\[=\sum_{j=1}^i a_j^2+\sum_{j=1}^i d_i^2 + \sum_{j=1}^i 2d_ia_j \]

\[=\sum_{j=1}^i a_j^2 + i \times d_i^2 + 2d_i \times j \]

放在右端比放在左端好转移就是相当于多加了 \(j+d_i\) 这一项
然后最后的答案 \(ans = min(n \times f(n,x) - x^2)\)

\(\text{P11316}\)

答案等于恰好0个 \(M \mid dist(i)\)
那么容易想到二项式反演
\(g_0 = ans\) 恰好0个满足条件
\(f_i\) 即钦定 \(i\) 有个剩下的对数不做要求
\(g_0 = \sum_{i=0}^n (-1)^i \binom{i}{0} f_i\)
那么距离整除 \(M\) 也就是两个位置 \(\mod M\) 同余
所以设 \(dp_{i,j}\) 表示前 \(i\) 个余数已经钦定了 \(j\) 对位置配对
\(dp_{i,j}\) += \(dp_{i-1, j - k} \times \binom{n - j + k}{k} \times \binom{cntk}{2k}\times (2\times k)\)!
也就是决定在 \(i\) 这个余数配对\(k\)个选出剩下的颜色,选出配对哪些位置,然后标序

\(f_i = dp_{s,j}\times (n - j)!\)

\(\text{P6847}\)

DS优化树形dp

\(\text{P4577}\)

启发式合并

\(\text{P5047}\)

正常做法:直接莫队,以移动右指针\(r+1\)为例,加上这个点对逆序对的贡献就是统计 \([l,r]\) 大与 \(r+1\) 的数的个数

优化:直接做会超时,那么这个可以差分一下 \([l,r]\) 中大与 \(r+1\) 的数的个数,等于 \([1,r]\) 大与 \(r + 1\) 的数的个数- [1,l-1]$$ 的数的个数,并且这一布优化还需要做到批量移动右端点
即同时加入 \(r+1,r+2,r+3...,qr\) 然后算贡献

  • \([1,r]\) 中大与\(r + 1\) 的数的个数很好算前缀和预处理,可以在\([r + 1, qr]\) 批量增加并且在移动右端点的时候右端点一直在移动,所以设 \(pre_i\) 表示 \(1\) 到 \(i\) 中比 \(i\) 大的数的个数 \(h_i\) 表示 \(pre_i\) 的前缀和,查询的时候可以直接把 \([r+1,qr]\) 的贡献批量加入
  • \([1,l-1]\) 中大与 \(r+1\) 的数的个数,这一部分是二次离线莫队的核心部分
    在移动右端点\(r\)的时候这一部分的查询左端点\(l\)一直不变,那么可以二次离线,用扫描线解决,核心是延后处理,暂时不计算当前的这部分贡献而是存储下来这个询问,把查询 \([r+1,qr]\) 挂在 \(l\) 上面,然后莫队做完之后统一做一次扫描线解决把贡献累积

\(\text{P4859}\)

这个糖比药多恰好药比糖多k个可以转换成糖必要多有恰好 K 个
\(g_i\) 表示 糖比药多的有恰好 \(K\) 个
\(f_i\) 表示 钦定有 \(i\) 对糖比药多其余任意,然后二项式反演
这里把糖和药从小到大排序,设 \(c_i\) 表示有多找药的能量比糖\(i\)能量小
设 \(dp_{i,j}\) 前 \(i\) 个糖匹配了 \(j\) 个糖比药多
那么 \(dp_{i,j} = dp_{i-1,j} + dp_{i-1,j-1} \times (c_i-j+1)\)
第二个很好理解,因为前面已经匹配了\(j-1\)个,所以这个位置有 \(c_i-j+1\) 种选法
最后套上二项式子反演

\[f_i = dp_{n,i} \times (n-i)! \]

\[ans=\sum_{i=k}^n(-1)^i\times f_i \]

\(\text{P10597}\)

为了方便计算,先把糖果标序计算最后再消序
然后还是二项式反演
\(g_i\) 表示恰好 \(i\) 个人手上糖果种类与原来相同
\(f_i\) 表示钦定了 \(i\) 个手上糖果种类与原来相同,其余任意
\(dp_{i,j}\) 表示前 \(i\) 种类糖已经有 \(j\) 个人拿到了原来种类相同的糖
\(dp_{i,j}\) += \(dp_{i-1,j-k} + \binom{tax_i}{k} \times A(tax_i,k)\)
也就是决定再 \(i\) 这个种类配对 \(k\) 个,然后可以从这些原来拿着 \(i\) 糖的人中选出 \(k\) 个人来,然后排列,这个\(k\)个人每个人分配不同的糖注意这里已经说过了是先把糖果标序计算,最后再消序

\(f_i = dp_{len,i} \times (n-i)!\)
然后二项式反演用 \(f\) 求 \(g_0\) 就可以了

\(\text{P5290}\)

这个题非常容易从特殊性质发掘正解
特殊性质:也就是 1 上面挂着两条链,这个时候只能分别选择两个链的节点放在同一个段
然后可以贪心的让一条链和另一条链的最大值放在一起,最后如果一条链方完了,那剩下的点和 1 只能单独开一个段
扩展到树上的情况,一个点开一个堆,记录这个点的段的大小有哪些,然后合并儿子信息的时候,可以发现每一个儿子应该是各选一个段然后把他们合并起来,并且这里肯定会贪心的选择恶每一个儿子最大的段合并,所以开一个堆用类似链的方法这样合并最后把根自己的信息加入

然后直接暴力合并超时容易想到启发式合并,然后就可以通过了

\(\text{P4072}\)

设每一天走了 \(h_i\) 的路
那么答案是

\[m \times \sum_{i=1}^m h_i^2 - S^2 \]

S是总路程
所以要让答案最小其实是最小化 \(\sum h_i^2\)
设 \(f_{t,i}=min_{j<i}(f_{t-1,j}+m(s_i-s_j)^2-2S(s_i-s_j))\)
写成斜率优化的形式直接上李超树就可以了

\(\text{P9084}\)

建笛卡尔树,树根是最大值

发现一次删除操作会删除笛卡尔树上所有只有一个儿子或者没有儿子的点原因是如果他没有儿子那么他两边都比他大,如果他只有一个儿子说明他必然有一边比他大
但是有一个特殊情况

原序列上的两边,指需要有一个儿子就可以满足被保留

那么考虑 \(dp\) 状态 \(f_{i,j,0/1}\)
表示长度为 \(i\) 的区间经过恰好 \(j\) 次被删除空,里面有/没有原序列边界

转移
设左区间需要 \(k\) 次删空
设右区间需要 \(l\) 次删空

  • 内部区间 \(f_{i,j,0}\)

    • 如果 \(k == l\) ,那么左右儿子会同时删空,那么根会在下一轮被删除因此整棵子树会再第 \(k+1\) 轮删空
    • 否则 \(k \ne l\) ,假设 \(k<l\) 那么再第 \(k\) 轮左儿子删空,第 \(k + 1\) 轮右儿子删空,但是之后右儿子还会继续删除
      直到第 \(l\) 轮删空,所以整棵子树会再第 \(max(k,l)\) 轮删空
  • 有一侧有边界 \(f_{i,j,1}\) ,边界具体再哪边不影响,假设边界再左边,那么再第 \(l\) 轮根的右儿子删空,那么根会在\(l+1\) 轮被删除,所以子树在第 \(max(k,l+1)\) 被删除空

答案:
设最大值的位置是 \(p\) 那么,左区间的长度是 \(p-1\) ,右区间的长度是 \(n-p\) ,所以整个区间在第 \(max(k,l)\) 轮删空

而题目要求在第 \(K\) 轮删空所以答案的类讲条件就是 \(max(p,n-p) == K\)

注意每一次区间最少删除一半的元素 \(K > 11\) 直接输出 \(0\) ,所以这个删空次数才能被设进状态

注意转移的时候要乘上组合树左子树大小选出树的结构

\(\text{P9212}\)

首先 \(x,y\) 模 \(m\)
考虑合法的 \(a_i\) 模 \(m\) 的范围

要求 \(a_i + x < a_i + y (\mod m)\)

  • 当 \(x = y\) 时 , 无解
  • 当 \(x < y\) 时,要么没有取模,要么都取模了
    所以合法的 $a_i \in [0, m - 1 - y] \cup [m - x, m - 1] $
  • 当 \(x > y\) 时,这个时候只能 \(a_i + x\) 取模而 \(a_i + y\) 没有取模
    所以合法的 \(a_i \in [m - x, m - 1 - y]\)

这个区间询问可以扫描线处理

也就是这个题相当与在模 \(m\) 意义下做了若干次值域查询

这个可以根号分治 ,设 \(s = \sqrt V\)

  • 当 \(m > s\) 时,直接暴力枚举模 \(m\) 的每一个商对应的余数区间。
    然后在值域上累加,用一个值域分块
  • 当 \(m \leq s\) 时,其一个桶,\(tax_{mod,v}\) 表示 模数为 \(mod\) 的时候有多少个余数 \(v\) 的值
    查询的时候暴力每一个合法的余数累加

\(\text{P2048}\)

求最大的 \(k\) 组子段和,满足长度在给定范围内,并且总和最大

前缀和一下,一个 \([l, r]\) 子段和等于 \(s_r - s_{l - 1}\)
那么把他挪动左端点一下,不受影响 \(s_r - s_l\)

那么对于每一个合法的 \(r\) 满足条件的 \(l \in [r-R,r-L]\)

那么对于每一个 \(r\) 以 \(r\) 为右端点的第 \(k\) 大子段和就是查询合法范围内第 \(k\) 小的 \(s_l\)
这个可以用可持久化线段树维护

然后目标是求 所有 \(r\) 中前 \(k\) 大的和
这个是一或粽子这样经典的选择方式
先把每一个右端点的第一大加入到堆作为备选序列
然后每一个序列如果选择了它的第 \(rk\) 大那就把他的第 \(rk + 1\) 大加入

\(\text{P5785}\)

这个题最重要的一点就是看到题目的第一要想到把后面的贡献提前计算,不要一上来就把转移设成二维的
设 \(h_i = \sum_{j=1}^i t_j, cs_i = \sum_{j=1}^{i} c_j\)

\(f_i\) 表示以 \(i\) 结尾作为一段的最小代价

然后转移 \(f_i = min_{0\leq j \leq i} {f_j+(h_i-h_j+s)(cs_n-cs_j)}\)
这个地方用 \(cs_n\) 减是因为现在用了的时间后面的开始时间就会更晚,直接在这里提前计算贡献
然后就可以李超树套公式优化了

\(f_i=min_j{-cs_jh_i+f_j-s\times cs_j-h_j \times cs_n + h_j \times cs_j}+ h_i \times cs_n + s\times cs_n\)

写成直线就可以了

\(\text{P2150}\)

这个题就是要让你选出两个数使得他们的质因数集合无交集
然后注意到 \(n \leq 500\)
那么一个数的质因数分解形式一定是这样的:
它会有前8大的质因数中的一些,然后最多有一个大与19的质因数,因为\(23\times 23 > 500\)

所以考虑根号分治,我们把所有数分解完之后保留他的大质数,然后把大质数相同的放在一组,每一组之间的大质数肯定不会产生冲突,所以每一组之间互不影响,分别处理

考虑装压 \(dp\) , \(dp_{mask1,mask2}\) 表示你选择的第一个人的小质数集合是\(mask1\),第二个人是 \(mask2\) 时的方案数

然后转移

  • 首先对于没有大质因数的集合,初始值 \(dp_{0,0}=1\),然后转移就是枚举每一个数,然后枚举 \(i,j\) 表示当前的质因数集合,然后转移条件时当 第一个人的小质数集合和 当前数包含的小质数无冲突时那么可以让第二个人选这个数,反过来也是一样

  • 然后一次处理每一个大质因数集合,那么要么两个人都选,要么两个人中的一个完全不选这个大质因数集合,另一个来选或不选
    那么设 \(f1_{i,j}\) 表示质因数集合分别为 \(i\) 和 \(j\) 的时候,并且当前的大质因数集合只由第一个人来选
    同时设一个 \(f2_{i,j}\) 表示的含义相同
    然后转移的时候和 \(dp\) 类似

\(f1\) 和 \(f2\) 的初始值就是 \(dp_{i,j}\)
但是最后把 \(f1\) 和 \(f2\) 合并到 \(dp_{i,j}\) 是 \(dp_{i,j} = f1_{i,j} + f2_{i,j} - dp_{i,j}\)
也就是两个人都不选的那些方案数不要算重复
最后答案就是所有不冲突的 \(i,j\) 的 \(dp_{i,j}\) 和

\(\text{P2523}\)

设 \(s_i\) 表示编号 \(\ge\) i 的人的个数
那么在放人的时候显然需要满足 \(s_i \leq n-i+1\)
所以设状态 \(f_{i,j}\) 表示 \(\ge i\) 的人中放了 \(j\) 个的方案数
然后转移就是 \(f_{i,j} = \sum_{k=0}^j f_{i+1,j-k} \times \binom{j}{k}\)
同时需要满足 \(s_i + j \leq n - i + 1\)

\(\text{P6189}\)

令 \(m = \sqrt n + 1\)

然后把所有数分为两类

  • 小数部分 这些数 \(<m\)
  • 大数部分 这些数 \(\ge m\) 且最多有 \(m-1\) 个

小数部分:

\(f_j\) 表示 \(1\) 到 \(m - 1\) 这些数 组成 \(j\) 的方案数
完全背包即可

大数部分

这里要求所有数都是 \(\ge\) m 的
所以这样构造大数:
每一次可以进行两种操作

  • 加入一个 \(m\)
  • 给所有数 \(+1\)
    所以设状态 \(g_{i,j}\) 表示 \(i\) 个大数的和为 \(j\) 的方案数
    所以 \(g_{i,j} = g_{i-1,j-m}+g_{i,j-i}\)

合并两部分
总答案是

\[ans = \sum_{j=0}^n f_j \times \sum_{i=0}^{m-1} g_{i,n-j} \]

\(\text{P5309}\)

考虑根号分治

对于 \(x > \sqrt n\) 的操作

这样的修改位置不会有很多直接暴力修改 \(a\) 的值

对于 \(x \leq \sqrt n\) 的操作

相当于对于所有 \(\mod x\) 余数为 \(y\) 的位置加 \(z\)

于是按照块长为 \(x\) 分块,每一个位置维护余数为 \(y\) 的加值
为了快速查询,另外维护一个加值前缀和,加值后缀和
查询的时候遍历所有模数
对于一个 \(l\) 和 \(r\) 可以用 \((l-1)/x + 1\) 和 \((r-1)/x + 1\)
快速算出左右端点位于哪一个块,然后如果位于同一个块,前缀和减一下就可以了
如果位于不同块,那么两边的散块用前后缀和查询一下

然后中间的整块:因为每一个整块的所有加值和都是一样的,
所以用当前模数的总加值和乘块个数就得到了

分块维护就可以了

\(\text{P9119}\)

首先因为三角形两边之和大与第三边,所以交叉一定比不交叉的路程长

所以因为不能交叉,所以我们连线的每一个时刻都一定是一个区间的点,不然跳过一个点连到了外面的点,再回来连这个点就一定会产生交叉

所以设 \(f_{l,r,0/1}\) 表示走完 \([l,r]\) 在左端点/右端点的最小代价
直接关路灯转移即可

posted @ 2026-10-09 12:28  wmq2012  阅读(8)  评论(0)    收藏  举报