2025.10 做题记录
圆圈排列 NOIP 模拟 T3(分析性质,刻画,计数 DP)
题意
有 \(n\) 个小朋友要在一个圆形操场上围成一圈做游戏,编号是 \(1, 2, \ldots, n\)。对于两个小朋友 \(a, b\),如果小朋友 \(a\) 沿着操场逆时针走到小朋友 \(b\) 的距离严格小于小朋友 \(b\) 沿着操场逆时针走到小朋友 \(a\) 的距离,那么小朋友 \(a\) 在小朋友 \(b\) 的西边,小朋友 \(b\) 在小朋友 \(a\) 的东边。如果两个小朋友走的距离相等,那么这两个小朋友是对称的。
小朋友们需要按指定的规则围成一圈,并且小朋友 \(i\) 沿着操场逆时针走遇到的第一个人是小朋友 \((i \mod n) + 1\)。规则可以简化为一个 \(n \times n\) 的矩阵 \(D\),矩阵正对角线上的元素 \(D_{ii} = *\),其他位置上的元素 \(D_{ij}\) 是 \(W\) 和 \(E\) 的其中一个,如果 \(D_{ij} = W\),那么小朋友 \(i\) 需要在小朋友 \(j\) 的西边,如果 \(D_{ij} = E\),那么小朋友 \(i\) 需要在小朋友 \(j\) 的东边。
现在给定了一个矩阵 \(D\),但是其中的一些非正对角线上的元素看不清,被替换成了 ?,你需要求出,对于将每个问号,如果将它们替换成 \(W\) 或 \(E\) 得到的所有矩阵中,有多少种矩阵可以让小朋友们按照相应的规则围成一圈。
由于答案可能很大,请输出对 \(998244353\) 取模的值。
\(n\leq 500\)。
题解
首先矩阵是反对称的,只用考虑一边。
其次,考虑尝试满足矩阵构造站立方案的过程,首先,矩阵从左到右必定是由 \(W\) 变成 \(E\),从上到下必定是从 \(E\) 变成 \(W\)。
这说明 \(W\) 和 \(E\) 之间有一条单调的分界线。
其次,我们不能让小朋友站位超过一圈,因此不能存在 \(i<j<k\) 使得 \(D_{i,j}=D_{j,k}=E\)。
令第一行第一个 \(E\) 在 \((1,x)\),那么分界线需要在 \(x\) 行结束,容易看出这是充要的。
枚举 \(x\),DP 即可。
数区间 NOIP 模拟 T4(另类 SGT 区间合并)
题意
维护一个序列,支持单点修改,全局查 \(\text{LCM}=v\) 的区间个数,\(v\) 每次询问给定。
\(n,m\leq 10^5,v\leq 10^9\)。
题解
考虑每次修改 \(x\) 时更新数 \(x\) 的贡献。
\(\text{LCM}\) 最多有 \(\log V\) 段,因此可以从 \(x\) 往前二分 \(\log V\) 段,往后二分 \(\log V\) 段,总共 \(\log V\) 个区间,暴力更新即可。
这样需要线段树维护区间 \(\text{LCM}\),复杂度 \(\log^2 n\log^2 V\),死翘翘。
由于区间总数是单 \(\log\) 的,考虑用线段树暴力维护,每个节点 \([l,r]\) 维护所有以 \(l\) 开始和以 \(r\) 结尾的 \(\text{LCM}\) 区间,合并是简单的,更新 \(x\) 贡献的时候在线段树上查出以 \(x\) 开头和结尾的区间即可。
最终复杂度(\(n,m\) 同阶) \(O(m\log^3 V)\),有一个 \(\log\) 是 \(\text{LCM}\) 贡献的,因此能过。
图 NOIP 模拟 T3(去重技巧)
题意
给定一个包含 \(n\) 个点 \(m\) 条边的简单无向连通图(无自环、重边),点编号为 \(1, 2, \ldots, n\)。
给定一个非负整数 \(k\),保证 \(0 \leq k \leq 2\)。
你需要对于所有满足 \(0 \leq i \leq k\) 的非负整数 \(i\) 求出,有多少种从 \(m\) 条边中选出 \(n - 1 + i\) 条边的方案,满足只保留 \(n\) 个点和选出的这 \(n - 1 + i\) 条边的图依然连通。
由于答案可能很大,所以你只需要求出对 \(998244353\) 取模后的结果。
\(n\leq 17\)。
题解
直接做子集 DP,进行两种操作:
- 用一条边合并两个连通块。
- 添加一条边。
钦定每次合并进来的连通块具有最小编号,这样每次转移时,一个状态会被算重 \(|E|\) 次,\(|E|\) 是这个状态的边数。
因为可以考虑一个状态的前一个状态,发现删去任何一条边都对应恰好一个上一状态。
蛋糕 NOIP 模拟 T3(计数,Raney 引理)
题意
对满足如下条件,下标范围为 \([0,n+1]\) 的序列计数:
- \(a_0=a_{n+1}=0\)。
- \(\sum\limits_{i=1}^{n} \max(0,a_i-a_{i-1})=m\)。
\(n,m\leq 2\times 10^5\)。
题解
求差分数组,相当于对满足如下条件的差分数组计数:
- \(\sum\limits_{i=1}^{n+1} d_i=0\)。
- \(\sum\limits_{i=1}^{n+1} \max(0,d_i)=m\)。
- \(\forall_{x\in [1,n+1]\cap \Z},\sum\limits_{i=1}^{x} d_i\geq 0\)。
考虑将原条件映射为:
- \(\sum\limits_{i=1}^{n+1} d_i=1\)。
- \(\sum\limits_{i=1}^{n+1} \max(0,d_i)=m+1\)。
- \(\forall_{x\in [1,n+1]\cap \Z},\sum\limits_{i=1}^{x} d_i>0\)。
映射方法为将第一个数 \(+1\),容易证明这是双射。
利用 Raney 引理:和为 \(1\) 的序列恰有一个循环位移使得任意前缀和大于 \(0\)。
那么直接对满足前两个条件的序列计数,最后再除以 \(n+1\) 即可。
对前两个条件计数只需枚举非负数的个数然后组合数即可。
等式 NOIP 模拟 T4(简单推式子)
题意
定义 \(f(a, b, m)\) 为最小的非负整数 \(x\) 使得其满足以下条件:
若不存在这样的 \(x\),则定义 \(f(a, b, m) = 0\)。
给定正整数 \(n, a, b\),你需要求出:
由于答案可能很大,所以你只需要求出对 \(998244353\) 取模后的结果。
题解
\(ax\equiv b \quad (\text{mod } m)\),即 \(x=\frac{b+m\times y}{a}\),\(y\) 取任意非负整数。
为了让 \(x\) 最小,必有 \(y=f(m,-b,a)\)。
当 \(m\bmod a\) 一样时,\(f(m,-b,a)\) 也一样,因此枚举 \(m\bmod a\),之后对答案的贡献是一个等差数列,直接求和即可。
P3623 [APIO2008] 免费道路 紫(Kruskal)
题意
给定一张图,边有黑色和白色之分,构造一个恰有 \(k\) 条黑边的生成树,或报告无解。
题解
普通生成树只要图连通就必定有解,我们先不加入黑边,这样图会分为若干百边连通块,把这些连通块缩成点,先用黑边跑一边 MST,这样保证剩下的图即使全选白边也是连通的,所以再在剩下的图中贪心选黑边即可。
CF1120D. Power Tree *2500(序列转差分,树论建模)
题意
Arkady 和 Vasily 在树上玩游戏。游戏分为三个阶段。第一阶段,Arkady 购买树上的一些非空顶点集合。第二阶段,Vasily 给所有叶子节点赋一些整数。第三阶段,Arkady 可以进行若干次(也可以不进行)如下操作:选择他在第一阶段购买的某个顶点 \(v\) 和某个整数 \(x\),然后将 \(x\) 加到 \(v\) 的子树中所有叶子的整数上。整数 \(x\) 可以是正数、负数或零。
Arkady 的目标是让所有叶子上的整数都变为零。无论 Vasily 在第二阶段如何赋值,Arkady 都要保证自己能够达成目标。请你求出 Arkady 在第一阶段至少需要支付的总费用 \(s\),以及有多少个顶点属于至少一个最优集合(即总费用为 \(s\) 的集合),使得 Arkady 购买这些顶点后能够保证胜利。
输出最优方案的并集。
题解
相当于让每个叶子独立,这放到树上不是很好做,把它拍到 DFN 序上,相当于有 \(n\) 个区间可以买,让一些关键点独立。
考虑差分数组,这些区间能让关键点的差分数组全为 \(0\)(最后一位除外)。
假设一个区间加在差分数组上的体现是 \(i\) 加 \(1\),\(j\) 减 \(1\),那么在 \(i,j\) 连一条边权为 \(c\) 的边表示能花 \(c\) 块钱让 \(i\to j\) 之间实现任意数值的转移。
那么最后我们需要让所有叶子和最后一位连通,即所有叶子连通,因此跑 MST 即可。
求可能成为 MST 边的并集,只需要按边权分类,对每个边权求:如果它是在同边权的边中第一个被加入的,那它是否可能被算入 MST。这是正确的,因为根据 MST 的性质,只加入 \(\leq w\) 的边(\(w\) 取任意数),图的连通情况是确定的。
CF888G. Xor-MST *2300(Boruvka,启发式合并)
题意
给定一个有 \(n\) 个点的完全无向图,每个点有一个权值 \(a_{i}\),点 \(i\) 与点 \(j\) 之间的边权为 \(a_{i} \operatorname{xor} a_{j}\)。
请你计算该图的最小生成树的权值。
题解
Boruvka 算法,每次让每个连通块往外找一条最短的边连上,不断重复这个过程。
每个连通块维护一个 Trie,全局维护一个 Trie,差分一下就能找到一个点往外连接的最小边。
合并连通块时做启发式合并即可。
注意 Boruvka 必须每个连通块往外找恰好一条边,而不是每个点找一条边。
CF1305G. Kuroni and Antihype *3500,但是这是假的 *3500(树论建模,枚举子集,另类 Kruskal)
题意
Kuroni 不擅长经济学。因此他决定创办一个名为 Antihype 的新型金融金字塔。其规则如下:
- 你可以免费加入金字塔,并获得 \(0\) 个金币。
- 如果你已经是 Antihype 的成员,你可以邀请你目前还不是 Antihype 成员的朋友,每邀请一位朋友,你将获得等于你年龄数目的金币。
最近有 \(n\) 个人听说了 Antihype,第 \(i\) 个人的年龄为 \(a_i\)。他们之间有些是朋友,但现在的友谊很奇怪:第 \(i\) 个人和第 \(j\) 个人是朋友,当且仅当 \(a_i \text{ AND } a_j = 0\)。
目前这 \(n\) 个人中还没有人是 Antihype 的成员。他们希望合作,以某种方式依次加入并邀请彼此,使得他们获得的金币总数最大。你能帮帮他们吗?
\(1\leq n\leq 200000,0\leq a_i\leq 200000\)。
题解
邀请与被邀请信息可以构成一棵树,
将所有 \(a_i \text{AND} a_j=0\) 的边连边 \(a_i+a_j\),那么容易发现答案就是最大生成树权值 \(-\sum a_i+\) 若干个连通块的 max。
为每个值建立一个虚点,虚点 \(v\) 下挂 \(a_i=v\) 的 \(i\),对虚点枚举超集建 \(v \text{AND} v'=0\) 的边,边数是 \(O({3}^{\log_2 n})\) 的,之后跑 Kruskal 即可。
直接 Kruskal 会 TLE,考虑在 \(\text{AND}=0\) 时,加法实际上是或运算,枚举边权后再枚举边权子集即可。
问题是我们这么做图不一定连通,而且答案最后的减 \(\max\) 会让连边不一定优,因此需要加一个 \(0\) 的虚点,即 \(a_{n+1}=0\),然后就能正常做了。
实现方面,按值缩点,维护 \(cnt\) 表示这个值的连通块个数。
ARC096 E - Everything on It *3100(二项式反演(容斥),集合划分计数,分类计数)
题意
有 \(n\) 部电影,她计划要每天和优太看几部。但他们作为具有精致电影品味的人,有如下几点要求:
- 她一天不能多次看同一部电影,也不能存在两天看的电影集合相同。
- 每部电影都要至少看两次!
- 可以存在某一天不看电影
每天的顺序不计,或是一天内看电影的顺序不计。我们只关心对于每个电影集合,是否存在一天恰好看了这些电影。
求在这样情况下不同的计划数有多少种,对质数 \(p\) 取模。
\(2\leq n\leq 3000\)。
题解
第一步容易想到容斥,钦定一些电影出现次数小于 \(2\),然后通过类似二项式反演的式子计算答案。
假设钦定了 \(k\) 个电影出现次数小于 \(2\),不妨设是 \(1\sim k\)。
考虑分类计数,把集合分为不包含 \(1\sim k\) 和包含 \(1\sim k\) 的两类。
对于不包含 \(1\sim k\) 的集合,\(k+1\sim n\) 的数随便选,结果为 \(2^{2^{n-k}}\)。
对于包含 \(1\sim k\) 的集合,枚举这样的集合个数 \(i\),对于一个固定的 \(i\),结果为 \(S(k,i)\times (2^{n-k})^i\),其中 \(S(k,i)\) 表示把 \(k\) 个不同的球放入 \(i\) 个相同盒子,球可以不使用的方案数。\((2^{n-k})^i\) 表示把每个含 \(1\sim k\) 的集合并上一个 \(k+1\sim n\) 的集合。
\(S\) 的推导类似斯特林数,\(S_{i,j}=S_{i-1,j-1}+S_{i-1,j}*j+S_{i-1,j}\),最后一项表示把当前球扔掉,前面是第二类斯特林数的转移。
你、组乐队了吧 NOIP 模拟T4(l-r 平面扫描线,历史和线段树)
题意
Sumimi 有两个 \(1, 2, \cdots, N\) 的排列 \(S\) 和 \(M\)。
当一个区间 \([l, r] (1 \leq l \leq r \leq N)\) 满足如下条件时,真奈会觉得自己的心意能够与小初产生共鸣。因此我们称这样的区间是 「两位一体」 的:
但是作为当红偶像,计划的变动是当然会有的。真奈一共有 \(q\) 天的计划,每天的计划是一个 \([1, N]\) 的子区间 \([L, R]\)。
对于每一天,真奈想知道在当天计划 \([L, R]\) 的限制下,究竟有多少 \([L, R]\) 的子区间 \([l, r]\) 是 「两位一体」 的呢?
题解
考虑放到 l-r 平面上,\(\min=i\) 的区间构成一个矩形,从这里入手。
那么对 \(S,M\) 分别算出 \(2\times n\) 个矩阵,表示区间在 \(S,M\) 的 \(\min / \max\) 为 \(i\) 的矩形,之后历史和线段树扫描线维护被覆盖两次的位置。
我在实现的时候把值反了过来,求的是 \(0\) 的个数,但是这不重要,因为都是最值计数。
最值计数的历史和线段树,维护的 \(histag\) 含义应为将所有子节点 \(\min\) 等于当前节点 \(\min\) 的节点计入历史和,而不是将 \(\min=0\) 的点计入,因为 \(\min\) 会发生修改。
这样写无需关心加法和计入历史和的标签顺序问题,也避免了先写矩阵再拆矩阵的麻烦。
P11673 [USACO25JAN] Median Heap G 蓝(重标数值,树形 DP)
题意
Farmer John 有一棵包含 \(N\) 个结点的二叉树,结点编号从 \(1\) 到 \(N\)(\(1 \leq N < 2\cdot 10^5\),\(N\) 为奇数)。对于 \(i>1\),结点 \(i\) 的父结点为 \(\lfloor i/2\rfloor\)。每个结点都有一个初始整数值 \(a_i\),以及将初始值修改为任意其他整数值的代价 \(c_i\)(\(0\le a_i,c_i\le 10^9\))。
定义近似中位数为:从最后一个结点 \(N\) 开始向前执行。在算法的每一步,如果一个结点不是它和它的两个结点的中位数,他就交换当前结点和值为中位数的子结点的值。在这个算法结束时,结点 \(1\)(根结点)上的值即为近似中位数。
有 \(Q\) 次独立的询问,每次询问给定 \(m\),求近似中位数等于 \(m\) 所需要的最小总代价。
题解
首先对于单次询问,有显然的 \(O(nV)\) DP,但是我们最后复杂度不能带 \(V\)。
考虑重标数值,由于我们只要求最终值等于 \(m\),中位数也只关心最后的数是否等于 \(m\),因此我们 DP 的时候只用关心当前点权和 \(m\) 的相对大小。
因此令 \(f_{i,0/1/2}\) 表示 \(i\) 子树内,结果小于/等于/大于 \(m\) 的最小代价。
我们 DP 的时候只用关心当前点权和 \(m\) 的相对大小,也能说明一个点被修改时,它的值一定改变了 \(</=/>m\) 的状态。
因为我们要处理多次询问,考虑让 DP 式子优美一些,令 \(w_{i,0/1/2}\) 表示将 \(i\) 改到 \(</=/>m\) 的最小代价,则 \(f_{i,Mid(i,j,k)}\leftarrow f_{ls,i}+f_{rs,j}+w_{i,k}\)。
注意到 \(w_{i,*}\) 只有两种取值且随 \(m\) 增长单调,因此进行询问离线,每次暴力修改所有改变的 \(w\),对修改的每个点的到根链更新 \(f\) 即可,由于题目给的二叉树深度是 \(O(\log n)\) 的,因此复杂度正确。
P11676 [USACO25JAN] DFS Order P 蓝(树形结构的区间 DP)
题意
Bessie 有一个无向简单图,结点编号为 \(1\dots N\)(\(2\le N\le 750\))。给定图的初始状态以及修改每条边状态的代价。具体地说,对于每对满足 \(1\le i<j\le N\) 的结点 \((i,j)\),给定一个整数 \(a_{i,j}\)(\(0<|a_{i,j}|\le 1000\)),其中
- 如果 \(a_{i,j}>0\),则边 \((i,j)\) 当前不在图中,可以以代价 \(a_{i,j}\) 添加。
- 如果 \(a_{i,j}<0\),则边 \((i,j)\) 当前在图中,可以以代价 \(-a_{i,j}\) 移除。
求使得 \([1,2\dots,N]\) 成为一个可能的 DFS 序的最小总代价。
题解
刚看到题没啥思路,点开标签,看到区间 DP 就会了。
DFS 树中,一个子树的编号一定是连续区间,因此可以区间 DP。
首先把 \(a_{i,j}<0\) 的边都删掉,然后令选择这些边的代价是 \(a_{i,j}\),这样问题转化为边的代价有正有负,选一个树加上所有负边权的返祖边,让边权和最小。
考虑区间 DP 出 dfs 树,然后把负边权返祖边加上。
考虑常见的树形结构区间 DP 的套路,令 \(f_{l,r}\) 表示区间 \([l,r]\),DFS 序可以为 \([l,l+1,\dots,r]\),\(l\) 为根的答案。
转移时枚举 \(l\) 的儿子节点 \(k_1,k_2,\dots,k_x\),要求 \(k_1=l+1\),此时返祖边必定有一端点是 \(l\),记 \(s_{i,j}=\sum\limits_{k=1}^{j} [a_{i,k}<0]a_{i,k}\),有 \(f_{l,r}\leftarrow \sum\limits_{i=1}^{x} f_{k_i,k_{i+1}-1}+a_{l,k_i}+s_{l,k_{i+1}-1}-s_{l,k_i-1}-[a_{l,k_i}<0]a_{l,k_i}\)。最后减的那项是因为 \(a_{l,k_i}\) 不能算重。
枚举 \(k_1,k_2,\dots,k_x\) 的过程本质上是区间划分 DP,因此倒着枚举 \(l\),对每个 \(l\) 做一遍区间划分 DP 即可。
P12031 [USACO25OPEN] Forklift Certified P 蓝(递归实现拓扑排序,二维数点转一维序列)
题意
农夫约翰(Farmer John)需要从一个旧仓库中清理 \(N\)(\(1 \le N \le 10^5\))个箱子,这些箱子被标记为 \(1\) 到 \(N\)。
这些箱子可以被建模为二维平面上的轴对齐矩形,其中 \(+x\) 方向是东,\(+y\) 方向是北。箱子 \(i\) 的西南角坐标为 \((x_{i1}, y_{i1})\),东北角坐标为 \((x_{i2}, y_{i2})\)。所有坐标都是范围 \([1, 2N]\) 内的整数,并且来自不同矩形的任意两个角都不会共享相同的 \(x\) 或 \(y\) 坐标。所有箱子都有非零面积,且没有两个箱子相交。
农夫约翰计划每次从仓库的西南入口处移除一个箱子。然而,由于叉车的物理限制,他只有在没有其他箱子的任何部分位于该箱子东北角的南方和西方时,才能移除该箱子。
下面显示了一个 \(N = 4\) 的示例。要移除箱子 4,阴影区域内不能有任何其他箱子。箱子 2 和 3 阻止了箱子 4 被移除,但箱子 1 不会。

帮助农夫约翰决定如何移除所有箱子!您的代码应根据整数标志 \(M\) 在两种不同的模式下运行:
- 模式 1(\(M = 1\)):生成一个 \(1, \dots, N\) 的排列,指定一个有效的箱子移除顺序。如果存在多个有效的顺序,则输出任意一个。可以证明这样的顺序总是存在的。
- 模式 2(\(M = 2\)):对于每个 \(k = 1, \dots, N\),如果农夫约翰可以在箱子 \(1, \dots, k-1\) 都已被移除的情况下移除箱子 \(k\),则输出 1,否则输出 0。
题解
第二问是好做的。
第一问,相当于对箱子拓扑排序。
建图是困难的,考虑拓扑排序的另一种实现方法:在反图上每次选择任意一条出边,递归下去。
因此我们只需要动态查询挡住一个箱子的任意一个箱子。
可以 bit 套 set 做到 \(O(n\log^2 n)\)。
由于 \(x,y\) 各不相同,因此可以二维转一维,将 \(x\) 视为下标,\(y\) 视为值,即 \(a_x=y\),有一个点在 \((x,y)\) 的右下方,当且仅当 \(\min\limits_{i\in [1,x-1]} a_i < y\)。线段树维护即可。
这启示我们拓扑排序问题不需要真正建图,只要我们能快速找到一个点的任意一个前驱,就能实现拓扑排序。
P11847 [USACO25FEB] True or False Test P 紫(决策单调性)
题意
Bessie 正在参加一场 \(N\) 道判断题的考试(\(1\le N\le 2\cdot 10^5\))。对于第 \(i\) 道题目,如果她答对了将获得 \(a_i\) 分,如果答错了将失去 \(b_i\) 分,如果不回答则分数不变(\(0<a_i,b_i\le 10^9\))。
因为 Bessie 是一头聪明的牛,她知道所有的答案,但她担心 Elsie(主考官)会在测试后追溯性地更改至多 \(k\) 道题目,使得 Bessie 无法答对这些题目。
给定 \(Q\)(\(1\le Q\le N+1\))个 \(k\) 的候选值(\(0\le k\le N\)),求对于每一个 \(k\),Bessie 在回答至少 \(k\) 道题目的前提下可以保证的分数。
题解
按 \(a_i+b_i\) 升序排序,相当于选一个分界线,使得分界线下面选 \(k\) 个 \(-b_i\),分界线上面全选 \(a_i\)。
发现分界线不一定具有单峰性质,因此考虑更一般化的性质——决策单调性。注意到 \(k\) 增大的时候分界线不能往下。因为如果分界线往下会更优,那 \(k\) 小的时候分界线往下也会更优,不符合最优性。
因此 \(k\) 越大,分界线越往前,分治即可。
AT_arc154_d [ARC154D] A + B > C ? 蓝(Adhoc,擂台算法,排序)
题意
PCT 君有一个 $ (1,2,\dots,N) $ 的排列 $ (P_1,P_2,\dots,P_N) $。你只知道 $ N $ 的值。
你可以向 PCT 君最多询问 $ 25000 $ 次以下的问题:
- 指定满足 $ 1\le i,j,k\le N $ 的整数三元组 $ (i,j,k) $,询问 $ P_i+P_j>P_k $ 是否成立。
请你求出 $ P_1,P_2,\dots,P_N $ 的全部值。
$ 1\le N\le 2000 $,交互库不自适应,但是自适应也能做。
题解
首先,\(1+1\) 不大于除 \(1\) 以外的任何数,所以可以 \(O(n^2)\) 次询问找到 \(1\)。
考虑优化,若 \(A_i+A_i<A_j\),则 \(A_j\neq 1\),若 \(A_i+A_i>A_j\),则 \(A_i\neq 1\),因此我们每次询问都能排除一个数,因此可以用类似擂台算法 \(O(n)\) 找出 \(1\) 的位置。
找出 \(1\) 的位置后,固定 \(A_i=1\),则条件转化为 \(P_j\geq P_k\),归并排序即可。
P12032 [USACO25OPEN] Lazy Sort P 紫(简单分析性质,组合数 DP)
题意
称一个序列是好的,当且仅当它能通过这种方式正确排序。
函数 LazySort(数组 a):
n = 数组 a 的长度
对于 t 从 1 到 1e100 执行:
对于 i 从 1 到 n-1 执行:
如果 a[i] > a[i+1] 则:
a[i] = a[i] - 1
a[i+1] = a[i+1] + 1
规定序列长度为 \(n\),有 \(Q\) 个位置固定,即有 \(Q\) 个限制 \((c,v)\),第 \(i\) 个限制为 \(a_{c_i}=v_i\)。
对好的序列计数。
题解
分析性质,发现好序列一定能被分成若干段,每段极差不超过 \(1\),每段的最大值递增,第一个数一定是这一段的最大值。
令 \(f_{i,0/1}\) 表示前 \(i\) 个数,第 \(i\) 个数是当前段最小值 \(+0/1\) 的方案数。
分 \(Q\) 段转移,先算 \(c_{i-1}\) 和 \(c_i\) 在同一段的情况。
之后,分类讨论 \(c_i\) 是不是一个段的开头,中间枚举有多少段,然后插板法分段,再乘上 \(2^{长度-段数}\) 转移。
乘积 NOIP 模拟 T1(折半,双指针)
题意
令质数 \(P = 10^7 + 19\),给定一个长度为 \(n\) 的整数序列 \(a\) 和一个整数 \(k \in [0, P-1]\),保证 \(\forall i \in [1, n]\),\(a_i\) 在 \([1, P-1]\) 之间等概率随机。
有 \(q\) 次询问,每次询问给定区间 \([l, r]\),问是否存在 \(l \leq t_1 \leq t_2 \leq t_3 \leq t_4 \leq r\),使得
若存在,则输出 \(1\);若不存在,则输出 \(0\)。
题解
注意到区间的期望长度是 \(O(^4\sqrt {p})\) 的,但是区间长度的 \(\max\) 大概是 \(O(\sqrt p)\),所以不能设阈值暴力。
考虑双指针,维护两个数相乘的桶,每次更新桶的时候 meet in the middle 计算四个数相乘等于 \(k\) 的数量,就可以双指针了。
简单环 NOIP 模拟 T2(模拟费用流)
题意
点 \(u\) 具有一个权重:\(\alpha_u\)。初始时,对于所有的 \(u\),\(\alpha_u = 0\)。
对于从 \(u\) 连向 \(v\)、边权为 \(w\) 的边,你可以:
- 花费 \(w\) 的代价,使得 \(\alpha_u\) 减一,\(\alpha_v\) 加一;
- 花费 \(w\) 的代价,使得 \(\alpha_u\) 加一,\(\alpha_v\) 减一。
一个局面是合法的,当且仅当:
- 能从初始局面(所有 \(\alpha_u = 0\))经过一系列上述操作后达到该局面;
- 对于所有的 \(u\),都有 \(|\alpha_u| \le C\)(\(|\cdot|\) 表示绝对值)。
小 G 给出 \(q\) 组询问,每次询问给定一个 \(\alpha\),求所有关于 \(\alpha\) 合法的局面中代价的最大值。
如果最大值可以无穷大,答案为 \(0\);否则答案为代价最大值对 \(998244353\) 取模的值。
题解
根据 \(q,c\) 的范围判断出 \(q,c\) 没啥用,进一步,这个问题的答案相当于 \(x=1\) 的答案,再乘上 \(x\)。
先写费用流,删去费用为 \(0\) 的增广路,发现本质上是选若干个端点不交的路径,使得绝对值长度之和最大。
考虑模拟费用流,求出前缀和,然后考查一条路径的贡献,发现本质上就是两个位置前缀和的差。
因此也不用什么高深的技巧了,把前缀和排序,答案就是前缀和数组后半截的和减去前半截的和。
P11845 [USACO25FEB] Min Max Subarrays P 紫(暴力)
题意
给定一个长为 \(N\) 的整数数组 \(a_1,a_2,\dots,a_N\)(\(2\le N \le 10^6\),\(1\le a_i\le N\))。输出所有 \(N(N+1)/2\) 个 \(a\) 的连续子数组的以下子问题的答案之和。
给定一个非空整数列表,交替执行以下操作(从第一个操作开始)直到列表大小恰好为一。
- 将列表内的两个相邻整数替换为它们的较小值。
- 将列表内的两个相邻整数替换为它们的较大值。
求最终余下的整数的最大可能值。
题解
傻逼题,看到操作先猜测长度是奇数取最大值,偶数取次大值,这显然是答案上界。
模拟发现 \(n\) 大的时候总能取到上界。
当 \(n\) 是大于 \(3\) 的奇数时,答案总取到最大值,因为只需要确保每次操作二用在最大值上即可。
当 \(n\) 为偶数时,有如下情况可以取到次大值:
- 把序列分成三块,最大值和次大值中间、最大值一侧、次大值一侧。
- 存在一侧至少有三个数。
这是因为,如果有一块的数字个数 \(\geq 3\),我们可以把其余两块消成大小 \(\leq 1\),之后用这一块攒出两个操作二把剩下的数消掉。
注意到 \(n>8\) 都满足上述条件,进一步,因为 \(n=8\) 时的唯一情况是 \(a_3,a_6\) 取最大或次大,模拟一下发现是可以取到次小值的。
只有 \(n\leq 6\) 时答案取不到上界,对 \(n\leq 6\) 的情况暴力即可。
[ARC107D] Number of Multisets *2100(计数 DP,刻画)
题意
给定正整数 \(N,\ K\)。有多少种有理数的多重集合满足以下所有条件?
- 多重集合的元素个数为 \(N\),元素的总和为 \(K\)。
- 多重集合的元素只能取 \(1,\ \frac{1}{2},\ \frac{1}{4},\ \frac{1}{8},\ \dots\),即只能是 \(\frac{1}{2^i}\ (i = 0,1,\dots)\) 之一。
答案可能很大,请输出对 \(998244353\) 取模的结果。
\(1\leq K\leq N\leq 3000\)
题解
考虑初始时所有数都是一,然后我们不断选择数分裂。
令 \(f_{i,j}\) 表示当前有 \(i\) 个数,有 \(j\) 个数是最大值的方案数。
为了避免重复,每次只让最大值分裂。
有转移方程 \(f_{i,j}\to f_{i+k,2\times k}\ \ (1\leq k\leq j)\)。
斜向差分优化即可。
[ARC107F] Sum of Abs *3100(网络流最小割,最大权闭合子图)
题意
给定一个 \(n\) 个点 \(m\) 条边的无向图,每个点有权值 \(a_i\) 和 \(b_i\)。
定义一个连通块的权值为其中所有点的 \(b_i\) 之和的绝对值。
可以删去任意个点,删去点 \(i\) 的代价为 \(a_i\)。
求:总权值(所有连通块权值之和)减去总代价(删点代价之和)的最大值。
题解
由一般图上删掉若干个点这个操作,可以推断这是流题了,除了网络流以外其余算法处理不了这个操作。
发现同一个连通块内点的贡献要么都是 \(b_i\),要么都是 \(-b_i\)。因此考虑最大权闭合子图的套路,先设定理想情况,所有 \(b_i>0\) 做正贡献,所有 \(b_i<0\) 做负贡献。
令理想的总权值为 \(\sum |b_i|\)。
如果 \(b_i>0\) 做负贡献,或 \(b_i<0\) 做正贡献,那么总权值会减小 \(2|b_i|\)。
如果删去一个点,总权值减小 \(a_i+|b_i|\)。
然后,如果 \(b_i>0\),向 \(S\) 连 \(b_i\) 边,如果 \(b_i<0\),向 \(T\) 连 \(-b_i\) 边。
拆点刻画删点操作,入点和出点连上 \(a_i+|b_i|\) 的边,之后连上原图边,边权为 \(+\infin\),答案为理想权值减去最小割。
最大权闭合子图套路:先假定理想贡献情况,再计算每个点不做理想贡献的损失,以损失为边权向源/汇连边,再按照点贡献之间的关系进行连边。答案为理想权值减去最小割。
P11677 [USACO25JAN] Shock Wave P 黑(分析性质,分析总变化次数,可删堆思想)
题意
Bessie 有 \(N\)(\(2 \leq N \leq 10^5\))块砖块排开在面前,分别需要至少 \(p_0,p_1,\dots,p_{N-1}\) 的力量才能击破(\(0 \leq p_i \leq 10^{18}\))。
Bessie 可以通过击打特定的砖块来施加力量,如果她选择击打砖块 \(x\) 一次,对所有在 \([0,N-1]\) 范围内的整数 \(i\),它将对砖块 \(i\) 施加 \(|i-x|\) 的力量。
请求出击破所有砖块所需要的最少击打次数。
题解
首先各种 DP 都没有任何前途。
考虑分析性质减少不必要的操作,对于一个操作 \(i\),肯定不能断言它能够被其他操作替代,考虑分析两个操作 \(i,j\),发现将操作 \(i,j\) 替换为操作 \(1,n\) 一定更优。
因此我们最后肯定是先操作若干次 \(1\),再操作若干次 \(n\),最后操作一次 \(m\ (2\leq m\leq n-1)\)。
考虑二分只操作 \(1,n\) 的最小操作次数 \(ans\),然后检查 \(ans-1\) 是否可行。
设 \(1\) 操作了 \(a\) 次,\(n\) 操作了 \(b\) 次,不妨设 \(2i\leq n\)(\(2i>n\) 同理),有如下式子:
强行提取 \(ans\) 的表达式 \(a+b\)。
当 \(2i>n\) 时,同理可得:
因此,只需满足 \(\max \frac{p_i-(a+b)(i-1)}{n-2i+1}+\frac{p_i-(a+b)(n-i)}{2i-n+1}\leq a+b\) 即可。
因此我们可以轻松求得 \(ans\),检查 \(ans-1\) 时,我们的式子又多出了一部分。(\(2i>n\) 的情况略)
我们希望对所有 \(m\) 维护一坨式子的最大值。
考虑这个式子的变化次数,\(\frac{|m-i|}{n-2i+1}\) 只会变化不超过 \(\frac{n}{n-2i+1}\) 次,因此总变化量是调和级数的。
实现方面,我们只关心最大的 \(\frac{p_i-(a+b)(i-1)-|m-i|}{n-2i+1}\),考虑让最大值递减,利用可删堆的思想,每次保证最大值更新即可。由于 \(a,b\geq 0\),我们不用处理任何式子是负数的情况。
必须要满足最大值递减才能保证优先队列做法正确,而 \(m\) 增加时只保证 \(i<m\) 的最大值递减,因此需要先从小到大枚举 \(m\),再从大到小枚举 \(m\),做两遍。
做两遍的时候需要控制优先队列中只保留 \(i>m\) 或 \(i<m\) 的数,因为多余的数可能无法更新到其本身的最大值,影响答案。
复杂度 \(O(T(n\log V+n\log^2n))\)。
P11678 [USACO25JAN] Watering the Plants P 黑(SlopeTrick)
题意
Bessie 的花园中有 \(N\) 株植物,从左到右编号为 \(1\) 到 \(N\)(\(2\leq N\leq 5\cdot 10^5\))。Bessie 知道植物 \(i\) 至少需要 \(w_i\)(\(0\leq w_i \leq 10^6\))单位的水。
Bessie 有一个十分古怪的灌溉系统,包含 \(N-1\) 条水渠,编号为 \(1\) 到 \(N-1\)。每条水渠 \(i\) 有一个相关的单位费用 \(c_i\)(\(1\le c_i\le 10^6\)),Bessie 可以支付费用 \(c_i k\) 来为植物 \(i\) 和 \(i+1\) 各提供 \(k\) 单位的水,其中 \(k\) 是一个非负整数。
Bessie 很忙,可能没有时间使用所有的水渠。对于每一个 \(2\leq i \leq N\),计算仅使用前 \(i-1\) 条水渠灌溉植物 \(1\) 到 \(i\) 所需要的最小费用。
题解
以下的 \(p\) 表示 \(w\)。
首先有一个显然的 DP,\(f_{i,j}\) 表示使用了 \(1\sim {i-1}\) 水渠,\(i\) 植物有 \(j\) 单位的水的最小代价。
则:
进行后缀和优化,令 \(sf\) 表示 \(f\) 的后缀 \(\min\)。
整体 DP,这相当于,每次把 \(f\) 在 \([0,p_{i-1}]\) 翻转,加上斜率为 \(c_{i-1}\) 的直线,再进行后缀 \(\text{chkmin}\)。
维护差分数组 \(t\),下标范围为 \([0,\max p]\)。
翻转 \(f\) 相当于将 \(t_0\) 设为 \(\sum\limits_{i=0}^{\max p} t\),然后将 \(t_{1\sim p_{i-1}}\) 翻转并取相反数,并将 \(t_{p_{i-1}+1\sim \max p}\) 推平为 \(0\)。
加上斜率 \(c_{i-1}\) 的直线,相当于 \(t_{1\sim \max p}\) 加 \(c_{i-1}\)。
考虑平衡树。
\(\text{chkmin}\),发现如果此时存在谷点,谷点处 \(t\) 的正负性改变,因此平衡树上二分出谷点,再推平即可。可以做到 \(O(n\log V)\)。
注意要特殊处理第一个植物,可以通过在序列最前面添加虚拟的 \(0\) 代价植物和 \(+\infin\) 代价水渠处理。
AT_arc190_b *2200
题意
有 \(N\times N\) 矩形,定义 \(K\) 阶 L 型为宽和高都是 \(K\) 的 L 型,显然使用 \(1\sim N\) 阶 L 型各一个可以将 \(N\times N\) 的矩形覆盖。
给定 \(a,b\),有 \(q\) 次询问,每次询问给出 \(k\),求 \((a,b)\) 被 \(k\) 阶 L 型覆盖的前提下,使用 \(1\sim N\) 阶 L 型各一个将 \(N\times N\) 的矩形覆盖的方案数。
题解
首先每次填入最大的 L 型,发现填法较为唯一,只能填边上,有四种情况。
每次放入一个 L 型,都会将矩形缩小一圈。
\((a,b)\) 被 \(k\) 阶矩形覆盖,需满足在 \(n-k+1\) 次缩小后,\((a,b)\) 位于边缘。
设使得 \((a,b)\) 满足上述条件的 \(n-k+1\) 次缩小的方案数为 \(cnt\),其中 \((a,b)\) 在矩形一角的方案数为 \(cnt'\),则这次询问的答案为 \(cnt\times (1+[k\neq 1])\times 4^{k-1}+cnt'\times [k\neq 1]\times 4^{k-1}\)。
考虑分析缩小操作,假设当前矩阵为 \([l_x,r_x],[l_y,r_y]\),缩小会分别将两个区间缩小 \(1\),可以缩左边也可以缩右边。不难发现对两个区间的操作是独立的。
设 \(n-k+1\) 次后的矩阵为 \([1+A,n-B],[1+C,n-D]\ \ (A+B=C+D=n-k+1)\),当 \(A,B,C,D\) 固定时,方案数为 \(\binom{A+B}{A}\binom{C+D}{C}\)。
在角上:分讨 \((a,b)\) 在哪一角,可以求得一侧 \(A,B,C,D\) 的值,组合数即可。
在边上:分讨 \((a,b)\) 在哪一边,可以求得 \(A,C\) 其中之一的值,另一个值是一个范围,以 \(1+A=a\) 为例,\(A=a-1,B=n-k-a+2,n-k+b< C< b-1\),答案为 \(\binom{A+B}{A}\times \sum\limits_{C} \binom{n-k+1}{C}\),每次 \(k\) 增大的时候增量维护 \(\sum\limits_{C}\binom{n-k+1}{C}\)。
代码咕咕咕。
模拟赛因为 T1 没对拍,大样例和手造样例都缺一种情况导致爆零,警钟长鸣。
P11675 [USACO25JAN] Photo Op G 紫(分析性质,分类讨论)
题意
Bessie 目前站在 xy 平面上 \((X,0)\) 处,她想要前往 \((0,Y)\)(\(1\le X,Y\le 10^6\))。不幸的是,\(N\)(\(1 \leq N \leq 3 \cdot 10^5\))头其他奶牛决定在 \(x\) 轴上摆姿势。更具体地说,奶牛 \(i\) 将位于 \((x_i,0)\),她的摄影师位于 \((0,y_i)\)(\(1 \leq x_i,y_i \leq 10^6\)),准备拍摄她的照片。他们将在时刻 \(s_i\)(\(1 \leq s_i < T\))开始摆姿势,并且他们会保持姿势很长时间(他们必须拍出完美的照片)。这里,\(1\le T\le N+1\)。
Bessie 知道每头奶牛的摄影安排,她将选择最短欧几里得距离到达目的地,而不穿越任何摄影师与其对应的奶牛之间的视线(她的路径将由一条或多条线段组成)。
如果 Bessie 在时刻 \(t\) 出发,她将需要避开所有在时刻 \(s_i \le t\) 开始摆姿势的摄影师-奶牛对的视线,此外令她到达最终目的地的距离为 \(d_t\)。求从 \(0\) 到 \(T-1\) 的每一个整数 \(t\) 的 \(\lfloor d_t\rfloor\) 的值。Bessie 可以从摄影师或者奶牛的位置经过,这样不算穿越视线。
题解
看到这道题的第一反应是我可以 bit 求出每个线段端点往 \(Y\) 轴走的位置区间,但是从左/右侧找第一个能往上走的点是错误的,答案的式子也不是简单的线性式子,因此我们无法动态维护答案。
我们分析两个线段交叉的情况,发现我们不能从中间穿过,换句话说,我们可以把相交的线视作一条粗线段。
显然,粗线段和粗线段还可以继续合并成更粗的线段。
所以我们可以使用 set 维护粗线段,这样所有线段之间不交,枚举相邻线段计算答案即可。
然后我们每次修改集合只会改变 \(O(1)\) 对相邻关系,使用 multiset 维护答案集合,动态修改即可。
插入 \((0,0)\) 和 \((+\infin,+\infin)\) 线段以避免边界的麻烦。
[AGC008F] Black Radius 黑(去重技巧)
题意
Snuke 君有一棵 \(n\) 个节点的全白的树,其中有一些节点他喜欢,有一些节点他不喜欢。他会选择一个他喜欢的节点 \(x\),然后选择一个距离 \(d\),然后将所有与 \(x\) 距离不超过 \(d\) 的节点都染成黑色,恰好操作一次,问有多少种可能的染色后状态。
两个状态不同当且仅当存在一个节点,它在两个状态中不同色。
部分分(1300pts/1900pts):Snuke 君喜欢所有节点。
题解
令 \(f(u,d)\) 表示 \(u\) 的 \(d\) 邻域,本题难点在于处理重复,考虑对于一个集合,只让最小的 \(d\) 计入贡献,即 \(f(u,d)\) 能被计入贡献当且仅当不存在 \(f(v,d+x)=f(u,d)\ \ (x\gt 0)\)。
这样做稍微有点问题,因为如果 \(f(u,d)=f(v,d)\),这样也会计重,讨论 \(f(u,d)=f(v,d)\),发现只有在 \(f(u,d)=[1,n]\cap \Z\) 时出现,因此我们特殊处理全集即可。
注意到重复关系具有单调性,若 \(f(u,d)=f(v,d')\) 则 \(f(u,d+1)=f(v,d'+1)\),因此只需要求出所有点最大的 \(d\) 然后求和即可。
考虑部分分,先把所有点的 \(d\) 最大值设成这个点到最远点的距离 \(-1\),然后考虑点 \(u\) 的最大 \(d\),记 \(u\) 为根时,其中一子节点为 \(v\),子树 \(v\) 深度为 \(h_v\),\(u\) 刨去 \(v\) 的最大深度为 \(h_u\),当 \(h_v < h_u\) 时始终有 \(f(v,d')\neq f(u,d)\ \ (d'<d)\),否则有 \(f(u,h_u+2)=f(v,h_u+1)\),更新 \(u\) 的最大 \(d\) 为 \(h_u+1\)。
把上面的话翻译成人话就是 \(u\) 的最大 \(d\) 为 \(u\) 刨去深度最大的子树后深度 \(+1\)。
考虑正解,此时对于每个 \(u\) 存在一个最小 \(d=d_{\min}\),当 \(d<d_{\min}\) 时不存在一个 Snuke 君喜欢的节点 \(x\) 使得 \(f(x,d')=f(u,d)\)。
当 \(x\) 是 Snuke 君喜欢的节点时,\(d_{\min}=0\)。否则我们仿照刚刚的思路找出最深子树 \(v\),记其余子树最大深度为 \(t\),\(v\) 中最靠上的 Snuke 喜欢的节点为 \(x\),则 \(f(x,dep_{x}+t)=f(u,2\times dep_{x}+t)\),那么 \(u\) 此处不应该被计算(因为 \(dep_x+t<2dep_x+t\))。对于其余子树,如果子树内有 Snuke 喜欢的节点,则其贡献为子树的最大深度 \(+1\)。
显然上面的 \(2\times dep_x+t\) 相比于下面的子树深度 \(+1\) 必定不优,因此上面的话翻译成人话就是:记含有 Snuke 君喜欢的节点的子树中,深度最小的子树为 \(w\),则 \(d_{\min}\) 等于子树 \(w\) 的深度 \(+1\)。
最大 \(d\) 同理,记 \(u\) 最大深度的子树为 \(v\),如果 \(v\) 内存在一个 Snuke 喜欢的节点,设这个节点为 \(x\),记 \(x\) 与 \(u\) 的深度为 \(dep_x\),次大子树深度为 \(t\),则 \(d_{u\max}=2dep_x+t-1\)。
我在玩原神,实际上 \(f(u,d)\) 被记录不一定保证 \(u\) 是 Snuke 喜欢的节点。本质上是我们对于每个合法的集合,选择使 \(d\) 最小的中心点 \(u\),将 \(f(u,d)\) 计入答案。
所以 \(u\) 的最大 \(d\) 就是 \(u\) 子树次大深度 \(+1\),和部分分结论一致。
如果某个 \(f(u,x)\) 能被 \(f(v,y)(y<x)\) 替代,那么有 \(d_{u\min}\geq x\),即 \(f(u,x)\) 存在,那么 \(f(v,y)=f(u,d)\) 也存在,即 \(d_{v\min}\geq y\),逻辑是自洽的。
换根即可。
CF1657E. Star MST *2200(计数 DP)
题意
如果一个无向图满足以下条件,则称其为“美丽图”:所有与顶点 \(1\) 相连的边的权值之和,等于该图的最小生成树(MST)的权值。
请计算恰好有 \(n\) 个顶点、边权值从 \(1\) 到 \(k\) 的所有完全美丽图的数量。由于答案可能很大,请输出对 \(998244353\) 取模后的结果。
\(2 \le n \le 250\),\(1 \le k \le 250\)。
题解
一道 *2200,但是想的时间还挺久的。
考虑模拟 Kruskal 的过程,并在同边权下优先选择与 \(1\) 向邻的边,如果存在一条边比所有没选的与 \(1\) 相邻的边都要小,且加上这条边不会成环,那么这张图就不合法。
假设 \(l\sim r\) 中与 \(1\) 相邻的边都是 \(x\),那么 \(l\sim r\) 之间的边的取值范围是 \([x,k]\)。
令 \(f_{i,j}\) 表示 \(i\) 个点(含 \(1\)),最大边权为 \(j\) 的方案数,从小到大分配 \(2\sim n\) 与 \(1\) 相连的边权。
转移时枚举边权为 \(j+1\) 且与 \(1\) 相邻的边数,式子比较简单,不写了。
显然这样不会算重,因为对于一个状态,其前驱状态唯一。
P12033 [USACO25OPEN] Package Pickup P 黑(线段树维护矩阵 DP)
题意
农夫约翰(Farmer John)按照以下奇怪的方式在数轴上分布了奶牛和包裹:
- 农夫约翰选择一个数字 \(M\)(\(1 \le M \le 10^{18}\))。
- 农夫约翰选择 \(N\)(\(1 \le N \le 2 \cdot 10^4\))个区间 \([L_i, R_i]\) 来分布奶牛(\(1 \le L_i \le R_i \le 10^{18}\))。然后他在位置 \(L_i, L_i + M, L_i + 2M, \dots, R_i\) 放置奶牛。保证 \(R_i - L_i\) 是 \(M\) 的倍数。
- 农夫约翰选择 \(P\)(\(1 \le P \le 2 \cdot 10^4\))个区间 \([A_j, B_j]\) 来分布包裹(\(1 \le A_j \le B_j \le 10^{18}\))。然后他在位置 \(A_j, A_j + M, A_j + 2M, \dots, B_j\) 放置包裹。保证 \(B_j - A_j\) 是 \(M\) 的倍数。
一旦奶牛和包裹分布完毕,农夫约翰想知道奶牛们捡起所有包裹需要多长时间。每一秒,农夫约翰可以用他方便的对讲机(walkie talkie)向一头奶牛发出指令,让其从当前位置向左或向右移动一个单位。如果一头奶牛移动到包裹所在的位置,它就能捡起该包裹。农夫约翰想知道,奶牛们捡起所有包裹所需的最少时间(以秒为单位)。
注意 \(M\) 是给定的。
题解
#define 草 包裹。
考虑暴力怎么做,贪心显然能做,但是没啥优化空间,考虑 DP。
显然奶牛不会在没有东西的地方掉头,考虑把奶牛和草的坐标排序,然后按照坐标顺序 DP。
将相邻的位置之间视为一个段,容易发现每个段只会被经过 \(0,1,2\) 次,令 \(d_i\) 表示第 \(i\) 段经过的次数,将问题转化为求一个符合条件的 \(d\) 使其加权和最小。
考虑分析 \(d\) 的充要条件,充要条件如下:
- 草旁边至少有一个位置非 \(0\)。
- 如果这个位置有一头牛,则两侧不能为 \(11\) 或 \(22\)。
- 如果这个位置有两头及以上牛,则不做任何限制。
- 所有非 \(0\) 段至少连接一头牛。
令 \(f_{i,1/2/3/4/5}\) 表示第 \(i\) 个位置,不考虑第 \(i\) 个位置是啥(这个限定是为了方便后面矩阵的边界处理),如下状态的答案。
- 上一段是 \(1\),未连接牛。
- 上一段是 \(2\),未连接牛。
- 上一段是 \(1\),已连接牛。
- 上一段是 \(2\),已连接牛。
- 上一段是 \(0\)。
转移显然。
考虑使用 \((\min,+)\) 矩阵维护 DP,注意到 \(M\) 是给定的,考虑将数轴划分为若干周期,即 \([0,M),[M,2M),[2M,3M)\dots\),当加入 \((l,r)\) 时,相当于修改了 \(l,r\) 中间的周期。
套路地扫描线,使用线段树维护一个周期的信息,具体地,将操作坐标离散化,线段树维护 \([0,M)\) 中所有操作涉及到的坐标,每个节点 \([x,y]\) 维护第 \(x\) 个坐标转移到第 \(y\) 个坐标的矩阵,以及最右侧坐标是一头牛还是两头牛还是草,并插入 \(0,M\) 为哨兵节点。还需要维护全 \(0\) 前缀长度和全 \(0\) 后缀长度来合并区间。
合并区间大概是算出中间长度 \(dis\),通过左侧区间最后一个非空坐标的状态(草/一头牛/两头牛)构造出中间转移一步的矩阵,之后将左侧矩阵、中间矩阵、右侧矩阵乘起来合并。
扫描线时,假设本次操作坐标为 \(x\),上一次操作坐标为 \(y\),则当 \(\lfloor\frac{x}{m}\rfloor\neq \lfloor\frac{y}{m}\rfloor\) 时,操作中间跨过了不少于 \(1\) 个周期,应该统计答案,从线段树根节点查询这个周期的转移矩阵,把答案乘上转移矩阵的 \(\lfloor\frac{x}{m}\rfloor-\lfloor\frac{y}{m}\rfloor\) 次方。
更新答案的过程和线段树合并区间的过程是一样的,可以将答案初值设成 \((\min,+)\) 单位矩阵,此时最后一行与 DP 初值恰好吻合,因此最后直接使用答案矩阵的最后一行作为 DP 数组即可,注意需要特判最后位置是牛还是草,因为我们 DP 时没有考虑最后一位。
P8096 [USACO22JAN] Drought G 蓝(计数 DP)
题意
FJ 的 \(N\) 头奶牛(\(1 \leq N \leq 100\))排成一行,队伍中的第 \(i\) 头奶牛的饥饿度为一个非负整数 \(h_i\)。FJ 可以选择两头相邻的奶牛 \(i\) 和 \(i+1\),令她们的饥饿度各减少 1。
FJ 想让他的奶牛饥饿度全部相同且非负。尽管他不知道他的奶牛们具体的饥饿度,他知道每一头奶牛的饥饿度上界;具体地说,第 \(i\) 头奶牛的饥饿度 \(h_i\) 至多为 \(H_i\)(\(0\le H_i\le 1000\))。
计算符合上述上界的 \(N\) 元组 \([h_1,h_2,\ldots,h_N]\) 的数量,使得 FJ 有可能达到他的目标,答案对 \(10^9+7\) 取模。
题解
第一反应是观察性质,直接在原序列上操作很难发现有用的性质,考虑转为差分序列后分析性质。
转为差分数组后可以发现将差分分为奇数下标和偶数下标,性质和差分数组的和有关,具体地,操作一次相当于把 \(d_i\) 的一个 \(1\) 转移到 \(d_{i+1}\),但是奇数下标差分数组的和是 \(O(nV)\) 级别的,无法 DP。
但是刚才的思考并不是没有用处的,因为我们可以通过差分数组证明,\(n\) 是奇数时,对于任意有解的序列,最后的值是唯一的,且等于 \(\sum_{i=2w+1\land i\leq n,w\in \N} d_i-d_{i-1}\),\(n\) 为偶数时,不难注意到对于任意有解的序列,假设其能够操作到 \(k\),那么最后一定能够操作到 \(0\)(在两两配对各执行 \(k\) 次操作即可)。
回到原序列上,\(n\) 是偶数时,考虑按位 DP 填数,\(f_{i,j}\) 表示 \(1\sim i\) 中 \(1\sim i-1\) 已经满足,且 \(i\) 操作了 \(j\) 次的方案数,目标是最后操作到 \(0\),转移显然,前缀和优化可以做到时间复杂度 \(O(nV)\)。
对于 \(n\) 是奇数的情况,需要额外枚举最后操作到的数,时间复杂度 \(O(nV^2)\)。
CF724F. Uniformly Branched Trees *2700(计数 DP,去重技巧)
题意
给定三个数 \(n,d,mod\),对满足如下条件的无根树计数,同构的树算作一棵:
- 有 \(n\) 个点,除了叶子以外所有点的度数都为 \(d\)。
\(n\leq 1000\),\(d\leq 10\),\(10^8\leq mod\leq 10^9\)。
题解
无根树去重技巧:钦定重心为根。
无序卷积去重技巧,加入 \(x\) 个重量为 \(y\) 物品,方案数为 \(\binom{f_y+x-1}{x}\)。
令 \(f_i\) 表示 \(i\) 个节点,根的度数是 \(d-1\),其余点度数为 \(d\) 的方案数,\(f_i\) 可以卷积得到。
卷积时如果两颗或多颗子树大小相同,则需要去重,具体地,加入 \(x\) 个大小为 \(y\) 的子树,方案数为 \(\binom{f_y+x-1}{x}\)。
再将 \(f_{1\sim \frac{n}{2}}\) 卷积得到根是重心的答案。
当 \(n\) 是奇数时已经做完了。
\(n\) 是偶数时,有两个重心且两边不一样的情况会被算重两次,因此将答案减去 \(\binom{f_{\frac{n}{2}}}{2}-f_{\frac{n}{2}}\) 即可。
P11846 [USACO25FEB] Transforming Pairs P 黑(二维平面,分类讨论,meet-in-the-middle)
题意
回答 \(Q\)(\(1\le Q\le 10^5\))个独立查询,每个查询的形式如下:
给定四个整数 \(a\),\(b\),\(c\),\(d\)(\(-10^{18}\le a,b,c,d\le 10^{18}\))。在一次操作中,你可以执行 \(a\mathrel{+}=b\),或 \(b\mathrel{+}=a\)。求将 \((a,b)\) 转变为 \((c,d)\) 所需要的最小操作次数,或者如果不可能完成,输出 \(-1\)。
弱化版:\(a,b\geq 0\)。
题解
对于弱化版,考虑正难则反,发现每一步是唯一的,辗转相除即可。
记 \(a,b,c,d\) 的答案为 \(\text{ans}(a,b,c,d)\)。
注意到:\(\text{ans}(a,b,c,d)=\text{ans}(-a,-b,-c,-d)=\text{ans}(b,a,d,c)=\text{ans}(c,-d,a,-b)\)。
因此所有不能归约到 \(a,b,c,d\geq 0\) 的情况,都能归约到 \(ac<0\land bd<0\) 或 \(a,c,d>0\land b<0\)。前者显然无解,考虑后者。
分析性质,\((a,b)\) 必定有一个时刻进行竖直方向移动,离开象限后进入第一象限,之后变为平凡情况。
对于不离开象限的情况,\((a,b)\) 的下一个状态唯一。画出 \((a,b)\) 不离开象限的路径图,发现图由若干个横线和竖线构成。
我们需要保证我们跳到第一象限的点能够到达。
分析从下面路径往上跳的性质,发现肯定是下面在横向行走时往上跳,往上跳的轨迹是一个斜率为 \(1\) 的线,这些线与上面的若干线段形成交点。
线段个数是 \(\log V\) 级别的,暴力枚举上面和下面的线进行 meet in the middle 即可,需要一些模拟的细节。
我们不需要考虑上面的竖线,因为根本不会和竖线相交,逆向考虑,如果相交那么这个竖线下一步会直接下来,因此交点必定是拐点,只考虑横线也能覆盖这个点。
P3349 [ZJOI2016] 小星星 紫(计数 DP,去重技巧,容斥原理,子问题划分技巧)
题意
给定一颗 \(n\) 个点的树,又给定一张 \(n\) 个点的图,需要将树中的 \(n\) 个点与图中的 \(n\) 个点一一对应,使得所有树中存在的边在图中能够找到与之对应的边。问对应方案数。
\(n\leq 17\)。
题解
没有任何思路,感觉怎样都要记录阶乘级状态。
考虑从树结构入手,把给定的树的 \(1\) 号点定为根,树为我们提供了一个子问题划分的结构。
令 \(f_{i,j,S}\) 表示图上 \(i\) 对应树上 \(j\),原树子树 \(j\) 内的点对应到了图上集合 \(S\) 的方案数。
直接转移需要枚举子集,复杂度爆炸。
有一个处理排列(即编号不重复)的容斥技巧,枚举 \([1,n]\cap \Z\) 的子集 \(S\),记不要求编号不重复,且只考虑原图 \(S\) 子集内的点的方案数为 \(g_S\),则 \(ans=\sum\limits_{S\in [1,n]\cap \Z} g_S\times (-1)^{n-|S|}\)。根据容斥原理的基本公式 \(\sum\limits_{i=0}^n \binom{n}{i}(-1)^i=[n=0]\) 即可得证。
令 \(f_{i,j}\) 表示图上 \(i\) 对应树上 \(j\),且原树子树 \(j\) 内已完成映射,不要求编号不重复的方案数,枚举 \([1,n]\cap \Z\) 的子集进行 DP,最后再容斥一下就做完了。
这种去重方法有一个名字叫做子集反演,具体内容如下:
记 \(f(S)\) 表示恰好使用 \(S\) 的答案(\(n\) 个点映射恰好使用了 \(S\) 中所有点),\(g(S)\) 表示至多使用 \(S\) 的答案(\(n\) 个点映射使用了 \(S\) 中的一些点),则有:
P8273 [USACO22OPEN] Pair Programming G 蓝(计数 DP,去重技巧)
题意
一个程序由一系列指令组成,每条指令都具有以下形式之一:
- \(\times pri_d\),其中 \(d\) 是一个 \([0,9]\) 范围内的一位数,\(pri_d\) 表示第 \(d-1\) 大的质数,并规定 \(pri_0=0\),\(pri_1=1\)。
- \(+s\),其中 \(s\) 是一个表示变量名称的字符串。一个程序中出现的所有的变量名均不相同。
程序执行的结果定义对表达式 \(0\) 依次应用每条指令后得到的表达式。例如,执行程序 \([\times 3,+x,+y,\times 2,+z]\) 得到的结果是表达式 \((0\times 3+x+y)\times 2+z=2 \times x+2\times y+z\)。不同的程序执行后可能会得到相同的表达式;例如,执行 \([+w,\times 0,+y,+x,\times 2,+z,\times 1]\) 也会得到表达式 \(2\times x+2\times y+z\)。
Bessie 和 Elsie 各有一个 \(N\)(\(1\le N\le 2000\))条指令的程序。他们将交错这些程序的指令以制造一个 \(2N\) 条指令的新程序。
计算执行 Bessie 和 Elsie 的交错程序可能得到的不同表达式的数量,对 \(10^9+7\) 取模。
题解
直接对最终形成的表达式计数是不现实的。
先考虑一些特殊情况和细节,首先 \(\times 1\) 可以删除。
对于 \(\times 0\),不知道咋特殊处理,考虑直接带着 \(0\) DP。
本题难点肯定在于去重,考虑分析操作序列性质,我们在钦定当前操作和下一步操作不同时(加变乘或乘变加),在结果不为 \(0\) 的前提下一定不会算重。
于是令 \(f_{i,j,0}\) 表示 Bessie 前 \(i\) 个指令和 Elsie 前 \(j\) 个指令,以 $+/\times $ 结尾且结果不为 \(0\) 方案数,\(g_{i,j}\) 表示 Bessie 前 \(i\) 个指令和 Elsie 前 \(j\) 个指令,结果为 \(0\) 是否可能。分段转移即可。
咕咕咕。
P4778 Counting swaps 紫(置换环,打表)
题意
给定一个排列 \(p_1, \ldots, p_n\),它是数字 \(1\) 到 \(n\) 的一个排列。在每一步中,你可以选择两个数字 \(x < y\) 并交换 \(p_x\) 和 \(p_y\)。
设 \(m\) 为将给定排列排序所需的最小交换次数。计算恰好用 \(m\) 次交换来排序给定排列的不同序列的数量。由于这个数量可能很大,计算它对 \(10^9 + 9\) 取模的结果。
\(1 \leq n \leq 10^5\)。
题解
唐氏打表题,考虑置换环,每个置换环独立,每次操作相当于把一个置换环分成两个置换环。
令 \(f_i\) 表示大小为 \(i\) 的置换环方案数,则:
含义是枚举操作的数对,除二是因为每个数对会算重两次。
不知道如何优化,打表发现 \(f_i=i^{i-2}\),然后就愉快的 AC 了。
考虑证明,通过式子不难想到无根树个数,定义 \(g_i\) 表示大小为 \(i\) 的无根树数量,根据 prufer 序列的性质,有 \(g_i=i^{i-2}\)。
考虑另一种求 \(g\) 的方法,为了去重,我们以重心为根进行 DP 求出 \(g\)。
则有:
含义是,在大小为 \(i-j\) 的基础上加入大小为 \(j\) 的子树,强制钦定除根外的最小值在新加入的子树内,并分配编号,枚举 \(g_{i-j}\) 中在这次转移后变为重心的点的最终编号(可以直接枚举最终编号的原因是,分配完编号后最终编号和之前的编号一一对应),去重双重心树。
发现 \(g=f\),证毕。
P14256 平局(draw) 黑(DP 套最优化)
题意
- 有 \(n\) 个人在石头剪刀布,每个人只会出固定的手势。你每次可以让相邻两个人石头剪刀布决斗,输的人被删除,如果平局就随便删除一个。求过程中的最多平局数。
现在你知道每个人分别是否可能出石头、剪刀、布,请对所有可能的出手方案求以上问题的答案之和。\(n≤3000\)。
题解
考场上写了 \(O(3^n\times n)\) 的暴力但是不知道为啥写挂了,于是淘汰了正确结论,然后交了个 \(O(3^n\times n^3)\) 就遗憾离场了 。
首先区间 DP 是没法放到 DP 套 DP 里面的。
考虑序列确定怎么做。
容易分析一些性质想到用栈模拟,但是想不清楚具体在干什么。
考虑把序列转化为类似括号的结构来操作,具体地,我们不关心手势具体是啥,只关心谁赢谁。
我们维护一个 \(b\) 序列表示将手势记作 \(0,1,2\) 后的差分序列,\(1\) 表示前赢后,\(-1\) 表示后赢前,\(0\) 表示平局。
显然可以先消去 \(0\),考虑产生 \(0\) 的方案。
- 对于 \(1,-1\) 子串,可以产生一个 \(0\) 并消失。
- 对于 \(-1,1\) 子串,没有贡献。
- 对于 \(1,1,1\) 或 \(-1,-1,-1\) 子串,可以产生一个 \(0\) 并消失,注意这种操作必定不优于操作一。
那么看前两个操作就可以想到把 \(1\) 视为 \((\),\(-1\) 视为 \()\),用栈模拟括号匹配,然后
此时我们可以直接设计 DP \(f_{i,j,k}\) 表示 \(1\sim i\) 位,栈里面有 \(j\) 个左,\(k\) 个右括号的方案数。
此时我们记录栈里面右括号个数仅仅是为了方便做操作三,考虑操作三的本质是什么,本质上是先把 \(-1,-1,-1\) 变为 \(1,-1\) 再匹配。
那么我们在对栈进行操作的时候,遇到两个 \(-1\) 直接把它变成 \(1\) 即可,这样栈中最多有一个 \()\),且必定在栈底,\(f_{i,j,0/1,k},g_{i,j,0/1,k}\) 表示原数组 \(1\sim i\) 位,栈中有 \(j\) 个 \((\),\(0/1\) 个 \()\),\(a_i=k\)(记录这个方便求 \(b\)) 的答案/方案数。
按找上述过程 DP 即可。
NOIP 模拟 T4(DP 套 DP,统计答案技巧)
题意
在一条数轴上有 \(n\) 台计算机,第 \(i\) 台计算机位于 \(x = a_i\) 处。
有两种窃取数据的方式:
- 花费 \(1\) 秒窃取长度为 \(20\) 的区间内的所有计算机数据;
- 花费 \(3\) 秒窃取长度为 \(75\) 的区间内的所有计算机数据。
注意:区间可以重叠,同一个位置可以被多次窃取。
每台计算机可能存放绝密文件,也可能没有,用 \(1/0/?\) 表示。对于所有可能的情况,计算最少花费时间的总和,并对 \(10^9 + 7\) 取模。
\(n\leq 1000\)。
题解
对最优化问题求和,不难想到 DP 套最优化或者 DP 套 DP。
本题的内层问题只能 DP,因此考虑后者。
考虑序列固定时如何求答案,令 \(f_{i}\) 表示处理 \(1\sim i\) 的最小花费,从第一个位置大于 \(a_i-20\) 和 \(a_i-75\) 的地方转移过来。
我们的转移“跨度”较大,如果要把这个 DP 当作内层 DP,那么我们需要记录一个位置大于 \(a_i-75\) 到现在的所有 DP 值。
考虑互换 DP 状态与值,令 \(f_{i,j}\) 表示 \(1\sim i\) 花 \(j\) 元是否可行,我们的目的是实现 \(f_i\to f_{i+1}\) 的唯一转移(不能有取 \(\max\)),因此将“是否可行”转为“最大向后延伸长度 \(+1\)(为 \(0\) 表示不能覆盖到 \(i\))”,就能按位转移了。
记 \(j_0\) 为最小的 \(j\) 满足 \(f_{i,j}>0\),则只有 \(f_{i,j_0},f_{i,j_0+1},f_{i,j_0+2}\) 有用,因为 \(f_{i,j_0+3}\) 一定不比在 \(f_{i,j_0}\) 的情况再在下一个 \(1\) 位置加上 \(75\) 区间优。
这样容易发现 \(f\) 的转移是唯一的。\(f\) 的缺陷是我们要么存储 \(j_0\),要么动态累计答案。
设计外层 DP,令 \(g_{i,j_0,x,y,z}\) 表示处理了 \(1\sim i\) 位,\(x=f_{i,j_0},y=f_{i,j_0+1},z=f_{i,j_0+2}\) 的方案数。
此时状态爆炸了,我们记录 \(j_0\) 是为了统计答案,考虑将答案拆贡献到每一步转移,具体地,设 \(g_{i,x,y,z}\) 表示处理了 \(1\sim i\) 位,\(x=f_{i,j_0},y=f_{i,j_0+1},z=f_{i,j_0+2}\) 的方案数,\(j_0\) 未知,转移本质上是在 DAG 上走,边权就是答案的增加量,答案就是所有路径的长度和。
这个 DAG 的性质是任意点到 \(n\) 的路径条数固定(为这个点后面的问号个数),当发生转移 \(g_{i,x,y,z}\to g_{i+1,nx,ny,nz}\) 时,若 \(x-(a_{i+1}-a_{i})\leq 0\),则答案会变大 \(1\),此时 \(ans\leftarrow ans+g_{i,x,y,z}\times 2^{cnt_{i+2}}\),其中 \(cnt_x\) 表示 \(x\sim n\) 的问号个数。
Longest Array Deconstruction *2100(DP 状态设计)
题意
Chanek 先生给你一个从 \(1\) 到 \(n\) 编号的序列 \(a\)。定义 \(f(a)\) 为满足 \(a_i = i\) 的下标 \(i\) 的个数。
你可以从当前序列中选择一个元素并将其移除,然后将剩下的元素拼接在一起。例如,如果你从序列 \([4, 2, 3, 1]\) 中移除第 \(3\) 个元素,得到的新序列为 \([4, 2, 1]\)。
你希望通过移除若干个元素(可以为零),使得 \(f(a)\) 最大。请你求出可以得到的最大的 \(f(a)\)。
题解
哎不知道为啥没想到。
朴素的 DP 是令 \(f_{i,j}\) 表示以 \(a_i\) 结尾,选择了 \(j\) 个的方案数。
仿照【CSP-S 2024 染色】,强制钦定状态每步转移都有新贡献,重新设计状态,\(f_i\) 表示 \(1\sim i\) 选了 \(a_i\) 个数的答案。
转移是 \(f_{i}\to f_{j}(j>i\land a_j-a_i\leq j-i)\),随便优化。
代码太简单了不写了。
NOIP 模拟 T1(行列二分图转化)
警示:\((x,y)\to (x\times V+y)\bmod p\) 是错误的,根据抽屉原理和多模哈希的实现,多少个模数冲突概率都很大。
题意
小 Y 现在正在模拟赛,但是一题不会。事已至此,他拿出了祖传棋盘。
这是一个 \(n\times n\) 的棋盘,每个格子上都有一个硬币,每个硬币只能是正或反。每次操作选择一个位置 \((i,j)\),然后将与这枚硬币在同一行或同一列的硬币全部翻面,需要注意的是,选择的这枚硬币不会翻面。
小 Y 很快将所有硬币翻成了正面,作为他的同桌,你自然不能落下。小 Y 会告诉你初始时棋盘上反面朝上的 \(k\) 枚硬币的位置。你希望求出将所有硬币翻成正面朝上的最小操作次数来薄纱小 Y。不过小 Y 的记性并不是很好,所以他给出的局面可能无解,如果无解,请告诉他 No Solution!。
题解
完全没往二分图上考虑/kel。
记有 \(a\) 个行被翻转,\(b\) 个列被翻转,则最终答案为 \(\min (a,b)\)。
特殊地,当 \(a,b\) 奇偶性不同是无解。
建立行列二分图,要求连边的点状态不同,没有连边的点状态相同。
这样确定第一行后所有列的状态就确定了,所有行的状态也确定了。
所以一共就有两种情况,模拟和判断是否符合题意都是简单的。
NOIP 模拟 T2(树形 DP,另类换根)
题意
小 W 初始有一棵以 \(1\) 为根的树,并且此时有一个虚拟结点 \(0\) 向 \(1\) 连了一条边(初始 \(1\) 的父亲为 \(0\))。他很喜欢变化这棵树的形态,于是他定义一次操作如下:
- 选择两个不为 \(0\) 且不同的点 \(u, v\),满足 \(u\) 是 \(v\) 的祖先。先将 \(v\) 与其父亲断开,再将 \(v\) 连向 \(u\) 的父亲作为新的父亲,最后将 \(u\) 与其父亲断开。此时将 \(u\) 所在连通块删除。
对于操作过程中,我们定义 \(0\) 的唯一一个儿子为当前树的根,所有结点的父亲都是相对于这个根来说的。
经过任意次操作后(可以不进行操作),小 W 对最后不同的树十分感兴趣(这里定义两棵树不同为确定根有标号的情况下不同构)。将所有最后不同的树放入集合 \(S\),小 W 需要你对于每个结点 \(x\) 计算出:
当然这个值可能很大,小 W 只需要你输出其对 \(998244353\) 取模后的结果。
\(n\leq 10^6\)。
题解
首先推出 DP 计算一号点的答案,令 \(f_u\) 表示只考虑子树 \(u\) 内,\(u\) 不进行操作也不被操作删除的方案数。则有 \(f_u=\prod_{v\in \text{son}_u}\left (\sum\limits_{x\in \text{subtree}(v)}{f_x}\right )\)。
维护 \(g_u=\sum\limits_{x\in \text{subtree}(u)}{f_x}\),即可 \(O(n)\) 计算。
计算其他点的答案相当于要求某个点不被操作删除,因此将这个点到根连的 \(g\) 减去其他子树的 \(f\) 的和即可,暴力可以过掉所有树高不是很高的点。
刚才的操作无法被拆贡献,祖孙关系确定也没法换根,然后赛时就不会了。
对于祖先关系确定的问题,可以使用自上而下的 DP 代替换根。
令 \(h_u\) 表示 \(u\) 以及 \(u\) 子树外,不考虑 \(u\) 子树内的操作且 \(u\) 不被操作删除的方案数。
第 \(i\) 个点的答案为 \(f_i\times h_i\)。
枚举 \(u\) 替换掉了哪个点,易得 \(h_u=\sum\limits_{v\in \text{Path}(1,fa_u)} h_v\times \left ( \sum\limits_{x\in \text{son}_v\land x\notin \text{Path}(v,u)}g_x \right )\)。
可以轻松做到 \(O(n)\),本质上式子和换根的差别应该是不大的,都是子树内刨去和 \(v\) 相连的点的贡献。
NOIP 模拟 T3(随机游走 Trick,势能函数)
题意
给定一个字符串 \(S\)。
你有一个打字机。这个打字机打出的第一个字符一定是 \(S\) 的第一位,之后打出的所有字符的概率分布只和它打出的上一个字符有关,并且按照如下规则进行:
- 将字符串 \(S\) 首尾相接连成一个环,记录下每种字符的下一个字符的种类和出现次数;
- 那么,如果它打出的上一个字符是 \(i\),此时它接下来打出字符 \(j\) 的概率为 \(\frac{cnt2_{i,j}}{cnt1_i}\)。
- 其中,\(cnt1_i\) 为字符 \(i\) 在 \(S\) 中的出现次数,\(cnt2_{i,j}\) 为顺序拼接字符 \(i,j\) 得到的子串在环状的 \(S\) 中的出现次数。
每个新打出的字符会接在上一个打出的字符的后面。
当 \(S\) 首次成为打字机打出字符串的子串时,记录下当前打字机打出的字符总数。求这个总数的期望值模 \(998244353\) 的结果。
\(|S|\leq 3\times 10^5\)。
题解
显然这相当于在 KMP 自动机上随机游走。
对于图上随机游走问题,设 \(f_u\) 表示 \(u\) 到目标节点的期望步数,令 \(f_n=0\),答案为 \(f_1+1\),转移为 \(f_u=\sum (1+f_v)\times p_{u\to v}\)。
注意到等式右侧概率和相同,因此我们把 \(f\) 集体加上某个值,仍然满足转移。
对于本题,需要额外设 \(f_{0,c}\) 表示没有匹配且当前字符是 \(c\),走到最后的期望步数。
不妨设 \(f_1=0\),答案为 \(-f_n+1\)。
则可以高斯消元算出 \(f_{0,c}\)
正序递推可以得到 \(f_{i}=f_{i+1}\times \alpha+\beta\),即 \(f_{i+1}=\frac{f_i-\beta}{\alpha}\)。
NOIP 模拟 T4(树剖,重链剖分拓展)
题意
给你一棵以 \(1\) 为根的树,每个点有点权,你需要完成 \(Q\) 次操作,操作分为 \(3\) 种:
- 给定三个非负整数 \(u,v,w\) ,表示你需要将 \(u,v\) 之间的简单路径上的每一个节点 \(x\) 的点权加上 \(fib_{dis+w}\) ,即斐波那契数列的第 \(dis+w\) 位,其中 \(dis\) 表示节点 \(x\) 到 \(lca(u,v)\) 路径上的边数。
- 给定两个整数 \(u,v\) ,你需要回答 \(u,v\) 之间的简单路径上的点权和。
- 给定两个整数 \(u,k\) ,你需要回答在所有与 \(u\) 距离不超过 \(1\) 的节点中,点权对 \(10^9+7\) 取模后,第 \(k\) 小的点权是多少(保证有解)。
答案对 \(10^9+7\) 取模。
\(w\leq 2\times 10^5,n,Q\leq3\times 10^5\)。
题解
为了解决 \(1\) 邻域查询,可以重剖后使用平衡树维护轻儿子。
剩余的部分就是 《fibonacci》的套路。
可以矩阵差分,也可以用公式 \(Fib_{n+m}=Fib_{n+1}Fib_{m}+Fib_{n}Fib_{m+1}\)。
由于 \(w\leq 2\times 10^5\),不需要矩阵。
[AGC022E] Median Replace 紫(DFA 上 DP(DP 套最优化),构建 DFA)
题意
由 \(0\) 和 \(1\) 组成的奇数长度 \(N\) 的字符串 \(X\),如果满足以下条件,则是美丽的:
- 可以进行 \(\frac{N-1}{2}\) 次如下操作,使得最终字符串唯一的字符为 \(1\)。
- 选择 \(X\) 中连续的 \(3\) 个比特,并用它们的中位数替换这三个比特。例如,对
00110的中间 \(3\) 个比特应用该操作后,字符串变为010。
- 选择 \(X\) 中连续的 \(3\) 个比特,并用它们的中位数替换这三个比特。例如,对
太一有一个由 0、1、? 组成的字符串。他想知道,将每个 ? 替换为 0 或 1,能够得到美丽字符串的方法数。请输出该方法数对 \(10^{9}+7\) 取模的结果。
题解
对于确定序列,判定时,使用栈结构模拟消除 \(000,011,101,110\),最后剩的如果全是 \(1\) 就是”美丽的“。
然后发现这样消除没有什么性质。
考虑将一些子串打包,来制造一些性质,具体地,如果栈底是 \(11\),则序列必定有解,直接结束,如果栈底是 \(01\),那么直接把 \(01\) 删掉,因为不管后面的数是多少,都和 \(01\) 无关(即 \(011=1,010=0\)),且就算 \(01\) 的 \(1\) 和后面操作,也会变成 \(1\),\(01\) 结构不变。
但是 \(10\) 似乎不满足这个性质,因为 \(10001=1\),而消掉 \(10\) 后会错。原因是 \(10\) 结尾的 \(0\) 可以和后面的 \(0\) 操作,将 \(10\) 后面的值由 \(0\) 变成 \(1\),而 \(01\) 没有这个问题。
那么我们的逻辑就是:
- 加入的数是 \(1\)。
- 如果栈中有恰好一个 \(1\),计入答案。
- 如果栈顶是 \(0\) 且栈只有一个元素,弹栈。
- 否则将 \(1\) 入栈。
- 加入的数是 \(0\)。
- 如果栈顶有超过两个 \(0\),弹栈。
- 否则将 \(0\) 入栈。
不难发现,栈中最多有两个 \(1\) 和两个 \(0\)。
考虑 DP 套最优化,令 \(f_{i,0/1/2,0/1/2}\) 表示只考虑原序列前 \(i\) 位,栈中有 \(0/1\) 个 \(1\) 和 \(0/1/2\) 个 \(0\) 的方案数,按照上述栈模拟方式 DP 即可。
推出这种 DP 的另一种方式是 Brzozowski 导数,大概方法是推出前缀恒等式,然后不断搜索直到状态形成闭包。
对于本题,初始状态为 \(\empty\)。
对于任意后缀 \(t\),都有:
- \(01t=t\),上述已经说明
- \(001t=0t\),因为为了消掉 \(00\),\(001\) 的 \(1\) 必须消失。
\(\empty\):
- \(+0=0\)
- \(+1=1\)
\(0\):
- \(+0=00\)
- \(+0=01=\empty\)
\(1\):
- \(+0=10\)
- \(+1=11\)
\(00\):
- \(+0=000=0\)
- \(+1=001=0\)
......
以此类推,得到 \(\empty,0,1,00,11,10,100,110,1100\)。
考虑接受状态,由于 \(n\) 是奇数,因此最后 DFA 状态的串长度肯定是奇数,当 DFA 状态为 \(1,110\) 时最后状态为 \(1\)。
为了实现方便,我们把 \(11+1\) 视为 \(11\),这样会改变长度奇偶,因此将 \(1100\) 和 \(11\) 也作为接收状态。
CF1582F2 Korney Korneevich and XOR (hard version) *2400(基础算法)
题意
给一个长度为 \(n\) 的序列 \(a_1,a_2,\dots,a_n\) ,寻找在 \(a\) 的所有递增子序列(可以为空)的异或和中出现的数。
题解
注意到 \(i<j\land a_i=a_j\) 时,以 \(j\) 位置结尾的异或和集合包含以 \(i\) 位置结尾的异或和集合,考虑按值操作。
\(V=5000\) 引导 \(O(V^2)\),令 \(dp_{i,j}\) 表示结尾值为 \(i\),且异或和为 \(j\) 的最靠前结尾。
从小到大枚举结尾值 \(i\) 和异或值 \(j\) 转移,转移时,记 \(a_i=x\) 的 \(i\) 集合为 \(pos_i\),则在 \(pos_{i}\) 找到第一个大于 \(dp_{i'(i'<i),j^i}\) 的位置转移到 \(dp_{i,j}\)。
将 \(dp\) 压成一维方便实现。
(DAG 计数,竞赛图,连通性)
题意
有 \(n\) 支队伍参加每场比赛。每支队伍有一个实力值 \(a_i\)。每两支队伍 \(i < j\) 恰好互相比赛一次。队伍 \(i\) 获胜的概率为 \(\frac{a_i}{a_i + a_j}\),队伍 \(j\) 获胜的概率为 \(\frac{a_j}{a_i + a_j}\)。
如果一支队伍直接或间接击败了所有其他队伍,则称其为“胜者”。如果存在一系列队伍 \(c_1, c_2, \dots, c_k\),使得 \(c_1 = a\),\(c_k = b\),并且对于所有 \(i\) 从 \(1\) 到 \(k-1\),队伍 \(c_i\) 击败了队伍 \(c_{i+1}\),则称队伍 \(a\) 直接或间接击败了队伍 \(b\)。注意,可能出现队伍 \(a\) 击败了队伍 \(b\),同时队伍 \(b\) 也击败了队伍 \(a\) 的情况。
求本次比赛中胜者数量的期望值,\(n\leq 14\)。
题解
一开始想了一些奇奇怪怪的东西,没有用竞赛图的性质。
竞赛图缩点之后一定是一个链,我们要求的就是第一个 SCC 的期望大小。
考虑枚举一个 SCC,只需要要求这个 SCC 内与这个 SCC 外的边都是内向外的,那么这个 SCC 就是第一个 SCC,且这样不会算重。
现在我们只需要知道对于任意集合 \(S\),它构成 SCC 的概率。
考虑模仿主旋律,记 \(f_S\) 表示 \(S\) 构成 \(SCC\) 的概率,\(g_S\) 表示 \(S\) 不是 SCC 的概率。
则 \(g_S\) 一定是若干个 SCC 拼成的 DAG,并且根据竞赛图性质,这个 DAG 是一条链。
因此:
其中 \(E(x,y)\) 表示将 \(x\) 的所有边都指向 \(y\) 的概率,需要先维护 \(Ev_{i,S},Evi_{i,S}\) 表示点 \(i\) 到集合 \(S\) 的正反向概率,再增量维护。
有了 \(f\) 就做完了。
CF1554E You *2600(计数,构造映射,观察答案)
题意
给你一个 \(n\) 个点的树,可以通过以下方式生成一个长度为 \(n\) 的序列 \(a\):
- 每次在树中选取一个未被标记的节点 \(u\),令 \(a_u\) 等于与节点 \(u\) 相邻的未被标记的节点个数,然后将节点 \(u\) 标记。
对于每一个整数 \(k\in[1,n]\),输出符合以下条件的序列 \(a\) 的数量模 \(998244353\) 的值:
- 序列 \(a\) 可以由给定的树通过上述方式生成;
- \(\gcd(a_1,a_2,\cdots,a_n)=k\)。
\(n\leq 3\times 10^5\)。
题解
咦?计数题你告诉我答案不超过 \(1\)?
一开始想了一些套路的东西,但好像都没有啥用。
首先注意到 \(\sum a_i=n-1\),然后就不会了。
或许可以通过暴力等手段发现(?),\(k>1\) 时答案为 \(0\) 或一,总答案为 \(2^{n-1}\)。
将原问题等价为给每个点赋一个权值,这些权值构成排列,一个点的 \(a\) 就是周围权值大于这个点的点个数。
进一步我们发现我们只关心权值的大小关系,图中的大小关系一共有 \(n-1\) 对,因此总方案数为 \(2^{n-1}\)。
考虑 \(k>1\) 时构造方案的过程,首先叶子节点必定比父亲小。
令 \(f_u\) 表示 \(u\) 是否比父亲后删除,则有:
- 当 \((\sum f_v)\bmod k=0\) 时,\(f_u=1\)。
- 当 \((\sum f_v)\bmod k=k-1\) 时,\(f_u=0\)。
- 否则无解。
因此 \(k>1\) 时答案是唯一的,之后再把 \(a\) 序列拿出来看一下 \(\gcd\) 是不是真正的 \(k\) 即可。
我们发现我们只需要枚举质数,然后计入最后 \(a\) 的 \(\gcd\) 的贡献即可。
并且只需要枚举 \(n-1\) 的因数,因为 \(\sum a_i=n-1\)。
时间复杂度 \(O(n\log n)\)。
CF1263F Economic Difficulties *2400(DP,树论)
题意
给你两棵树,结点分别是 \(1,\dots A\) 与 \(1,\dots B\),然后给了 \(N\) 台设备,并且 \(A\) 树和 \(B\) 树的叶子结点(两棵树的叶子节点数量相同)都是链接电机的。
求最多可以删掉几条边,使得每个电机都能连到任意一棵(或两棵)树的根节点(\(1\) 号点)。

题解
为什么要使用了网络流?为什么要使用了网络流?为什么要使用了网络流?
首先我们转换一下问题,相当于求最小保留边数。
假设我们钦定了一个集合被上面的电网连接,那么对答案就是这些点到根链的并集大小。
而这道题恰好保证的叶子 DFS 序递增,根据虚树结论,新加入一个点 \(i\) 时,记上一个同侧点为 \(j\),则保留边数增加了 \(dep_{i}-dep_{\text{lca}(i,j)}\)。可以增量维护贡献。
令 \(dp_{i,j,1/2}\) 表示处理了 \(1\sim i\),上一个与当前点不同侧的点是 \(j\) 的最小保留边数,简单 DP 即可,复杂度 \(O(n^2\log n)\),使用线性 LCA 算法可以做到 \(O(n^2)\)。
现在这个 DP 形式与【CSP-S 2024 染色】十分相似,也许可以优化到 \(O(n\log n)\) 或 \(O(n)\),但我不会。
CF383E Vowels *2700(SOSDP)
题意
有一本包含 \(n\) 个“三字词”的词典。一个三字词是由第一个 \(24\) 个英文字母(\(a\) 到 \(x\))中任意三个小写字母组成的序列(正好 \(3\) 个)。她规定其中一些字母为元音,其他的则为辅音。整个语言基于一个简单规则:只要单词中至少包含一个元音,该单词就是正确的。
Iahubina 想知道对所有可能的元音集合(共有 \(2^{24}\) 种),每种集合中正确单词数的平方的 \(xor\) 总和。请帮助 Iahub 求出这个数字。
题解
看到题解第一行高维前缀和就会了,咋回事呢。
首先平方后异或无任何特殊性质,因此需要求出对于所有集合 \(S\),元音为 \(S\) 的单词个数。
令 \(f_S\) 表示集合 \(S\) 的答案,第一反应是构造 \(f_S\to f_{S\cup \{x\}}\) 的转移,但发现行不通。
集合包含关系,考虑高维前缀和,将三字词容斥拆成七个贡献在跑 SOSDP 就做完了。
CF348D *2500(格路计数,类反射容斥)
题意
有一个 \(n\times m\) 的网格图,有一些位置有障碍物,不能通行。
有两只乌龟从 \((1,1)\) 出发前往 \((n,m)\),两条路径除起点和终点外点不相交。
对行走方案计数,认为两只乌龟相同。
\(n,m\leq 3000\)。
题解
首先一条路径只能 DP,所以两条路径要么是 DP 优化,要么是容斥状物。
我们发现如果 DP 出两条路径,状态信息量是 \(O(n^3)\)(认为 \(n,m\) 同阶)的,非常不能优化。
考虑容斥,第一反应是枚举第一个或最后一个相交的点,对一侧不做要求,对另一侧要求不交。
但是发现这样会把原问题切分成子问题,子问题仍然无法快速解决,复杂度退化至 \(O(n^4)\),然后我就不会了。
考虑格路计数中对最后一个交点操作的套路,将最后一个交点往后的两条路径翻转之后终点互换,构造不合法方案与某个规模相同问题答案的映射。
首先要确定不同的起点和终点,可以发现本题的第一步和最后一步固定,令 \(f(a,b,c,d)\) 表示 \((a,b)\) 走到 \((c,d)\) 的单个路径条数,总方案数可以转化为 \(f(1,2,n-1,m)\times f(2,1,n,m-1)\)。
考虑将最后一个交点后的坐标翻转,则不合法方案数为 \(f(1,2,n,m-1)\times f(2,1,n-1,m)\)。
容易证明这个转化是正确的,即 \(f(1,2,n,m-1)\times f(2,1,n-1,m)\) 与不合法方案构成双射。
(VP)CF2159B Rectangles *????(基础算法)
题意
给定一个二进制网格 \(G\),其尺寸为 \(n \times m\)。
我们将一个矩形定义为元组 \((u,d,l,r)\),需满足以下条件:
- \(1 \le u < d \le n\);
- \(1 \le l < r \le m\);
- 单元格 \((u,l)\)、\((u,r)\)、\((d,l)\)、\((d,r)\) 均为 \(1\)。
矩形 \((u,d,l,r)\) 的面积定义为 \((d-u+1) \cdot (r-l+1)\)。
对于每个单元格 \((i,j)\),请找到所有满足 \(u \le i \le d\) 且 \(l \le j \le r\) 的矩形 \((u,d,l,r)\) 中面积的最小值,如果不存在这样的矩形,则输出 \(0\)。
\(n\times m\leq 250000\)。
题解
[xinyoudui模拟赛]
(VP) [AGC001D] Arrays and Palindrome *????(构造)
题意
高桥くん的母亲在高桥生日的时候送了他 \(a, b\) 两个数列。因为 \(a, b\) 满足了如下的所有性质, 所以他非常高兴:
- \(a\) 数列的数字总和是 \(N\);
- \(b\) 数列的数字总和是 \(N\);
- \(a, b\) 中包含的数都是正整数;
- 满足以下两个条件的数列, 所有元素必定是相同的。
- 最开始的 \(a_1\) 个元素, 接下来的 \(a_2\) 个元素,更后面的 \(a_3\) 个,等等,都是回文;
- 最开始的 \(b_1\) 个元素, 接下来的 \(b_2\) 个元素,更后面的 \(b_3\) 个,等等,都是回文。
但是有一天,高桥把把数列 \(a\) 和 \(b\) 都弄丢了, 幸运的是,他知道数列 \(a\) 是另一个长度为 \(M\) 的序列 \(A\) 的排列。
为了让他再一次高兴起来, 他妈妈决定给他另一对数列使其满足如上性质。
\(1≤N≤10^5\),\(1≤M≤100\),\(1≤A_i≤10^5\)。
题解
手模一下发现有三个奇数时无解。
又发现若干个偶数可以交错拼接。
因此分讨一下就构造完了。
所以为什么我做了 50min 呢?
[AGC001E] BBQ Hard *????(组合意义)
题意
给定 \(n\) 和 \(n\) 个数对 \((a_i,b_i)\),求:
\(n\leq 2\times 10^5\),\(1\leq a_i,b_i\leq 2000\)
题解
不知道咋优化,考虑组合意义。
\(\dbinom{a_i+a_j+b_i+b_j}{a_i+a_j}\) 相当于从 \((0,0)\) 到 \((a_i+a_j,b_i+b_j)\) 的路径条数。
将 \(i\) 和 \(j\) 分开,相当于 \((-a_i,-b_i)\) 到 \((a_j,b_j)\) 的路径条数。
直接按 \(1\leq i,j\leq n\) 算,相当于点对之间路径条数和,DP 后修一下式子中 \(i=j\) 的边界即可。
重做了种树、染色、括号序列。
CF1111E. Tree *2500(DFS 序上 DP)
题意
给定一棵有 \(n\) 个节点的树,以及 \(q\) 个询问。
每个询问以三个整数 \(k\)、\(m\) 和 \(r\) 开头,接着是树上的 \(k\) 个节点 \(a_1, a_2, \ldots, a_k\)。对于每个询问,假设树以 \(r\) 为根。我们需要将给定的 \(k\) 个节点分成最多 \(m\) 个组,满足以下条件:
- 每个节点恰好属于一个组,每个组至少有一个节点。
- 在任意一个组内,不能存在两个不同的节点,使得其中一个节点是另一个节点的祖先(无论是直接还是间接的祖先)。
你需要输出每个询问的方案数,对 \(10^9+7\) 取模。
题解
点集询问考虑建立虚树。
建立虚树后跑计数 DP,由于我们要考虑祖孙关系,直接自下而上合并不能优于 \(O(nm^2)\),考虑按 DFS 序 DP,令 \(f_{i,j}\) 表示考虑 DFS 序在 \([1,i]\) 的点,分 \(j\) 组。
则 \(f_{i,j}\leftarrow f_{i-1,j-1}+f_{i-1,j}\times (j-dep_i)\),表示新开一组或分为之前的任意一组。
这样我们只需要知道有多少颜色和当前点冲突(即 \(j-dep_i\)),而无需进行复杂的树形背包合并。
P7077 [CSP-S 2020] 函数调用 蓝
题意
某数据库应用程序提供了若干函数用以维护数据。已知这些函数的功能可分为三类:
- 将数据中的指定元素加上一个值;
- 将数据中的每一个元素乘以一个相同值;
- 依次执行若干次函数调用,保证不会出现递归(即不会直接或间接地调用本身)。
在使用该数据库应用时,用户可一次性输入要调用的函数序列(一个函数可能被调用多次),在依次执行完序列中的函数后,系统中的数据被加以更新。为了计算出正确数据,小 A 查阅了软件的文档,了解到每个函数的具体功能信息,现在他想请你根据这些信息帮他计算出更新后的数据应该是多少。
\(0 \le a_i \le 10^4\),\(T_j \in \{1,2,3\}\),\(1 \le P_j \le n\),\(0 \le V_j \le 10^4\),\(1 \le g^{(j)}_k \le m\),\(1 \le f_i \le m\)。
题解
函数调用关系是一个 DAG,使用虚拟节点依次调用 \(f_1,f_2\dots f_Q\) 可将原问题转化为 \(Q=1\) 的问题。
一开始想的是维护每个数 \(\times p+q\) 的标签,后来发现对每个数维护较为困难,因此考虑对最终的操作序列入手。
具体地,我们希望可以对于求出所有 \(+\) 操作,它后面所有乘操作的乘积和,即对于每个 \(1\) 类函数 \(x\),记操作序列为 \(op\),求 \(\sum\limits_{id_i=x}\sum\limits_{j=i}^{opcnt} op_i(v)[op_i(type)=2]\)。
考虑拓扑排序,记 \(g_u\) 表示完整调用函数 \(u\) 的操作序列的乘积,\(h_u\) 表示操作序列中完整调用 \(u\) 后(不含 \(u\))的乘积和,转移较为自然,正序倒序分别做一遍拓扑即可。
赛前打板子。。。

浙公网安备 33010602011771号