1.19~2.2 外出集训做题记录
*:自己未独立想出的题。
**:未完成严谨证明的题。
+:重做之前做过的题。
260119A(容斥系数 DP)
题意
你决定写一首歌。
首先你需要写出一段旋律,抽象地说,一段旋律是一个只包含 \([1,k]\) 中的整数的数组。
最开始你认为,一段符合你审美的旋律应该形如若干个 \(1 \sim k\) 的排列依次拼接而成。
后来你降低了标准,具体地:假若一段旋律符合你之前的审美,那么这段旋律的所有连续子段都符合你现在的审美。
给定 \(n,k\),求长度为 \(n\) 的,符合你现在的审美的旋律数目。
\(1\leq n\leq 10^{18}\),\(1\leq k\leq 750\)。
题解
贪心匹配的判据是不对的,考虑直接暴力容斥,枚举可能的分割点集合,可以推出方案数是若干关于 \(p_i,p_{i-1}\) 与 \(p_1,p_{cnt}\) 的系数相乘。
原因形如两个错位的区间都是排列,\((a,b],(c,d](a<c<b<d)\),前面已经确定,因此 \((b,d]\) 与 \((a,c]\) 数字集合相同,\((b,d]\) 只需要确定这些数的顺序,直接乘上一个阶乘就行了。
然后进行容斥系数 DP,需要枚举 \(p_1\),复杂度 \(O(k^3)\)。
赛时因为写成 \(O(k^3\log)\) 挂了 \(36\) 分。
*260119B(全 \(0\) 矩形边框计数,矩形分治,指定贡献顺序)
题意
给定 \(01\) 矩阵,求全 \(0\) 矩形边框计数(只要求边框全 \(0\))。
\(1\leq n,m\leq 2000\)。
题解
直接做是 \(O(n^3)\) 的,考虑矩形分治,如果能以短边乘长边或短边平方解决跨分割点的问题,那么复杂度就是正确的。
枚举上下边界 \(i,j\),然后需要求 \(i,j\) 往外延申的极长的一段 \((i,t1),(j,t2)\),中间打通的位置个数(即 \(\sum\limits_{x=mid}^{\min(t1,t2)} [(i,x) 到 (j,x) 全 0]\))。
直接从上往下扫不弱于二维偏序,必须多带 \(\log\),总共 \(\log^2\) 无法接受。
本质上是我们固定了上面像下面贡献的贡献顺序,实际上是没有任何道理的。
记 \(i\) 往右侧延申的长度为 \(toR_i\),钦定贡献顺序为 \(toR_i\) 小的贡献到 \(toR_i\) 大的。
然后变成了一维偏序,维护方法是维护 \(c_{i,j}\) 表示 \(i\) 向 \(j\) 的贡献,每个 \(i\) 贡献形如 \(O(m)\) 个 \(c_i\) 上的区间加,即对于 \(mid\leq x\leq m\),求 \((i,x)\) 向上向下延申的极长位置下标 \(L,R\),做 \(c_{i,L\sim R}\) 的区间加,进行差分后求前缀和。
最后左右对位乘起来即可。
\(O(nm\log nm)\)。
*260119C(Lucas 定理,Kummer 定理,数位 DP)
题意
求 \(\sum\limits_{ax+by=k\land x,y\in \N} \binom{n+x-1}{n-1}\binom{m+y-1}{m-1}(c_0+c_1x+c_2y+c_3xy)\) 模 \(p\) 的值。
\(n,m,k\leq 10^{18}\),\(a,b\leq 50\),\(0\leq c_0,c_1,c_2,c_3<p\leq 10^6\),\(p\geq 2\)。
题解
考查 \(m=c_0=c_1=c_2=c_3=0\) 的情况,本题不弱于求单个组合数,考虑使用 Lucas 定理。
其中 \(n_i,m_i\) 是 \(n,m\) 的 \(p\) 进制分解形式。
考虑先将 \(a,b,k\) 除以 \(\gcd(a,b)\),使用 exgcd 找到一组 \(y\) 最小的解 \((x_0,y_0)\),之后有 \(x=x_0-bi,y=y_0+ai\)。
原式可以化简为:
其中 \(U=n+x_0-1,V=m+y_0-1\)。
考虑 \(c_1=c_2=c_3=0\) 怎么做,对 \(U-bi\) 和 \(V+ai\) 做 \(p\) 进制数位 DP,记 \(f(i,j,k)\) 表示低 \(i\) 位,前者进位 \(j\),后者进位 \(k\) 的权值和。
复杂度是 \(O(Lab\times p)\),\(L\) 为位数。由于 \(p\) 大的时候 \(L\) 极小,可以通过所有 \(c_1=c_2=c_3=0\) 的点,但是过不了 \(a,b\leq 50\)。
当 \(i\) 确定时 \(U-bi\) 和 \(V+ai\) 当前位都确定了,所以记录两个进位是不必要的,具体地我们维护 \(ax+by\) 的进位,记当前进位为 \(t\),下一位进位为 \(t'\),则 \(ax_i+by_i+t=k_i+pt'\),\(t'=\frac{ax_i+by_i+t-k_i}{p}\),即 \(t'=O(a+b)\)。
因此我们舍弃之前的不定方程通解形式,数位 DP 维护 \(ax_i+by_i\),可以做到 \(O(L(a+b)\times p)\)。
根据 Kummer 定理,\(\binom{A+B}{A}\) 的 \(p\) 因子数是 \(A+B\) 进位的次数,因此 \(\binom{n-1+x}{n-1}\) 中上面一旦进位,组合数值就是 \(0\),因此无需记录 \(n-1+x\) 的具体值。
考虑一般情况,对于其余的项,我们只关心 \(x,y\) 的 \(p\) 进制末尾数字,在最低位记录即可。
具体地记 \(f_{i,j}\) 表示低 \(i\) 位 \(t=j\) 的权值和,转移枚举 \(x\),计算 \(y\) 和 \(t'\)。
260120A(简单构造)
题意
给定一个 \(n\) 个点的树,每个点有点权 \(a_i\in \{0,1\}\)。
构造一个长为 \(2(n-1)\) 的序列,序列中的元素是树上的边,其中每条边出现两次。需要满足按序列中边的顺序进行如下操作,操作不会失败:
- 对于边 \((u,v)\),若 \(a_u\neq a_v\),交换 \(a_u,a_v\),操作成功。若 \(a_u=a_v\),操作失败。
\(2\leq n\leq 10^6\),保证有解。
部分分:只有一个 \(1\)。
题解
部分分相当于模拟一个 DFS 过程。
链怎么做,缩连通块,可以依次消连通块,但是剩两个连通块会出问题,此时交换边界的 \(0,1\),两边是独立的,且满足部分分限制,两边分别 DFS 即可,最后再换回来。
一般情况,缩点,与链完全相同,删到只剩两个连通块就是链的最后一步。
因为保证有解所以不会出现全 \(0\) 或全 \(1\) 的情况。
*260120B(分析性质,放宽条件作用范围,主次依附转移,bit 优化 DP)
题意
给定一个排列 \(a\),记其前缀最大值位置的集合是 \(c\),你可以选一些位置挖空,满足挖空后符合 \(c\) 的排列中,字典序最小点排列恰好为 \(a\)。
对选位置的方案计数。
\(1\leq n\leq 10^6\)。
部分分 \(a_1=n\)。
题解
启示:实时检查得出的条件限制是否多余。
分析性质,猜测以下条件充要:
- 对于任意的 \(i,j\),若交换 \(a_i,a_j\) 后仍然满足 \(c\) 的限制,且 \(a_i>a_j\),则 \(i,j\) 不能同时选。
继续分析什么样的 \((i,j)\) 不会爆,发现:
- 对于 \(c=0\) 的 \(i,j\),必须满足 \([i<j]=[a_i<a_j]\)。
- 对 \(c=1\) 的 \(i\),记上一个 \(c=1\) 的位置是 \(x\),下一个是 \(y\),若选择 \(a_i\) 则 \(y\) 后面不能选择 \((\max (a_x,\max\limits_{t=i+1}^{y-1}a_t),a_y)\) 之间的数字。
直接做有两维限制。但是发现 \(y\) 前面必定不存在 \((\max (a_x,\max\limits_{t=i+1}^{y-1}a_t),a_y)\) 之间的数字,因此“\(y\) 后面”的限制是多余的,直接删去。
这样我们的问题转化为有一些数字,分为两类:
- 第一类:必须构成上升子序列。
- 第二类:选择后会存在一个区间不能选数。
考虑主次依附 DP,上升子序列计数不好刻画,因此选择第一类为主要元素,假设选择了 \(a_i,a_j(i<j,a_i<a_j)\),乘上 \(2^{f(a_i+1,a_j-1)}\) 表示有多少第二类元素的限制区间在 \([a_i+1,a_j-1]\) 内。
由于区间不交,把右端点拿出来,记 \(c_i\) 表示右端点小于 \(i\) 的区间个数,\(f(l,r)=c_r-c_{l-1}+O(1)\),取决于:
- 是否有区间包含 \(l\)。
- 是否有区间同时包含 \(l,r\)。
这都是好处理的,将 \(2^{c_r}\) 和 \(2^{-c_{l-1}}\) 拆出,使用 bit 优化 DP,在处理一下 \(O(1)\) 的细节即可。
*QOJ1838. Intellectual Implementation(扫描线,图上容斥,点减边容斥)
题意
求两两不交的矩形的无序无重复三元组数,下标之间互不相同,\(1\leq n\leq 200000\)。
题解
对于满足 XXX 条件的计数,当条件可以刻画为一个点数比边数多 \(1+O(1)\) 个点的图时,可以使用点减边容斥(算所有符合条件的点数减去符合条件的边数)。本题中将相交矩形的代表元视为【上边界最靠下的矩形上边界】的重合部分,相当于一条链,其中点数比边数多 \(1\)。
先离散化。
记 \(c_i\) 表示和 \(i\) 相交的矩形个数。
容斥每个相交限制,有 \(ans=all - (\sum c_i)/2 * (n-2) + \sum \binom{c_i}{2} - (两两相交矩形三元组数)\)。
- 求 c_i,c_i=n-【不交矩形个数】,不交的条件是 \(Rj<Li \lor Li>Rj \lor Dj<Ui \lor Di>Uj\),容斥,存在条件互斥因此只有八项,每项维度不超过二,二维数点,使用 bit。
- 求【两两相交矩形三元组数】,交集必定包含上边界最靠下矩形的上边界,对【上边界最靠下的矩形上边界】的重合部分点减边。对矩形上边界的点:钦定包含这个点,记包含这个点且上边界大于当前的矩形个数为 \(d\),方案数为 \(\binom{d}{2}\)(选两个矩形和当前矩形相交)。边同理进行扫描线,维护区间 \(\binom{d}{2}\) 和。实现时维护区间的 \(0,1,2\) 次方和即可。
\(O(n\log n)\),常数较大。
*[ARC120F1] Wine Thief(交替容斥)
题意
给定一个长为 \(n\) 的序列 \(a\),从中选 \(k\) 个数,满足任意两个数不相邻。
称一个选数方案的权值为被选中的 \(a_i\) 的和。
求所有选数方案的权值和。
\(1\leq 2k\leq n\leq 3\times 10^5\)。
题解
考虑没有不相邻的限制怎么做,唯一的方法似乎是拆贡献,答案为 \(\sum\limits_{i=1}^{n} a_i\binom{n-1}{k-1}\)。
加上限制。首先我们会求方案数,记作 \(f(n,k)=\binom{n+1-k}{k}\),定义 \(f(x,y)=[y=0]\quad (x\leq 0)\)。
仍然拆贡献,枚举选择的数 \(a_i\),删去 \(a_{i-1},a_{i+1}\),剩余使用 \(f(n-3,k-1)\),但是会漏掉 \(a_{i-2},a_{i+2}\) 都选的情况。
容易发现我们很难简单的转化为形如 \(f(i,j)\) 的子问题,遇到这种情况,可以考虑对特殊情况交替容斥,补上 \(a_{i-2},a_{i+2}\) 都选,删去 \(a_{i-3\sim i+3}\) 再算,此时漏掉了 \(a_{i-4},a_{i+4}\) 都选,再以此类推即可。
具体地,答案为 \(\sum\limits_{i=1}^{n} a_i \sum\limits_{j=1}^{\frac{i+1}{2}} f(n+1-4j,k+1-2j)\)。
\(f(n+1-4j,k+1-2j)\) 和 \(i\) 无关,预处理前缀和即可。
需要特殊处理边界的细节。
*QOJ9687. 仙人掌染色(打表,观察性质,圆方树 DP,012 背包)
题意
给定平面上的 \(n\) 个点,第 \(i\) 个点的坐标为 \((x_i, y_i)\)。给定 \(m\) 条边,第 \(i\) 条边连接结点 \(u_i, v_i\)。保证由这 \(n\) 个点与 \(m\) 条边构成的无向图为仙人掌图。
初始时,所有的 \(m\) 条边都是白色的。你可以选择若干条边,并将其染成黑色,其中将第 \(i\) 条边染成黑色的代价为 \(w_i\)。
对于每对有公共结点的异色边,设从白色边开始沿公共结点逆时针转 \(x\) 条边可以到达黑色边,那么可以获得 \(p\times x\) 的能量。特别地,对于两条共线且方向相同的边(即另一结点关于公共结点的极角相同的边),规定先到达编号较小的边,也即,编号较小的边的极角更小(两边极角相邻时 \(x=1\))。
求染色后可以获得的能量总和减去染色代价总和的最大值。
\(2 \le n, m \le 2 \times 10^5\),\(1 \le p \le 1000\),\(0 \le w_i \le 10^4\),\(0 \le x_i, y_i \le 10^7\)。
部分分:图是树。
题解
贡献的计算形式相当于对每个点,其邻域的边构成环,在环上选两个点转。
打表发现,一个点的贡献总和只与其邻域中黑边的边数有关,与边顺序无关,因此点的坐标没有用。
证明考虑交换相邻的异色边,发现带来的影响可以相互抵消。
记度数为 \(d\),选择 \(k\) 个点的贡献为 \(f(d,k)\),按照黑边都在一起的情况计算,是等差数列求和套等差数列求和的形式,\(f(d,k)=p(d-k)\times \frac{\frac{k(k+1)}{2}+\frac{k(2d-k-1)}{2}}{2}=p\times \frac{(d-k)kd}{2}\)。
先考虑树怎么做,树上 DP,\(f_{u,0/1}\) 表示 \(u\) 子树内,指定 \(u\) 的父边被染黑的最大贡献。
转移时,由于 \(f(d,k)\) 与子树内贡献之间无特殊联系,为了计算此时的 DP 值,我们需要对于每个 \(1\leq k\leq deg_u\),求 \(u\) 的儿子中选 \(k\) 个 \(f_{v,1}\),其余选 \(f_{v,0}\) 的最大值。按 \(f_{v,1}-f_{v,0}\) 排序并贪心即可。
考虑圆方树,此时一个圆点有两个父边,记 \(f_{u,0/1,0/1}\) 表示 \(u\) 子树内,指定 \(u\) 在父亲所在环的【前驱边】和【后继边】是否选择,\(u\) 子树内的最大价值。
当尝试计算 \(f_u\) 时,我们关心的是,\(u\) 每个方点儿子对应环中,\(u\) 所相邻的两个边是否选择。
在每个儿子方点所在环做环上 DP,计算 \(g_{v,0/1/2}\) 表示选了 \(0/1/2\) 条和 \(u\) 相邻的边的最大贡献。
与树的部分同理,我们需要对于每个 \(1\leq k\leq deg_u\),求 \(u\) 的儿子中 \(g\) 的第二维和为 \(k\) 的 \(g\) 最大和。
这是一个经典的贪心问题(CF436E),使用反悔贪心,每次使和增加 \(1\)。
分以下几种情况,用堆维护即可:
- 选 \(g_{v,1}\)。
- 选 \(g_{v,2}\),退 \(g_{v',1}\)。
- 选 \(g_{v,2}\),退 \(g_{v',2}\) 至 \(g_{v',1}\)。
- 改 \(g_{v,1}\) 至 \(g_{v,2}\)。
由于要对每个 \(k\) 求出答案,不能按下标顺序加点,需要按堆中权值大小顺序上述进行操作。
特判方点度数为二的情况,此时如果两个点之间有重边照常算(事实上数据无重边),否则 \(g_{v,2}=-\infin\)。
注意算贡献时如果边被算重需要减去。
\(O(n\log n)\)。
*QOJ10269. Easy Counting Problem(最优化计数,DP 状态优化,DP 的组合意义优化)
题意
给定一个数组 $ A $,你可以执行以下操作零次或多次:
- 选择一个下标 $ i \((\) 1 \leq i \leq |A| $),使得 $ A_i = i $,并从数组 $ A $ 中删除第 $ i $ 个元素。
令 $ f(A) $ 表示在最优地应用操作后,$ A $ 的最小可能长度。
给定整数 $ N $ 和 $ M $,求所有长度为 $ N $ 且满足 $ 1 \leq A_i \leq M $(对所有 $ 1 \leq i \leq N $)的数组的 $ f(A) $ 之和。由于答案可能很大,请输出对 998244353 取模的结果。
\(1\leq n,m\leq 10^9\),\(|n-m|\leq 2000\)。
题解
最优策略是每次找最后一个操作,但不便于推广。
记前面被删除的个数为 \(cnt\),\(A_i\) 能被删除当且仅当 \(i-cnt\leq A_i\leq i\)。因此记 \(f_{i,cnt}\) 表示前 \(i\) 个数中删除 \(j\) 个的方案数,可以做到 \(O(n^2)\)。
注意到 \(|n-m|\) 很小,尝试讨论 \(n\) 与 \(m\) 的大小关系。
当 \(n\leq m\) 时,\([i-cnt,i]\) 总是包含在 \([1,m]\) 中,此时 \(f_{i,j}\leftarrow jf_{i-1,j-1}+(m-j-1)f_{i-1,j}\)。
我们最后要求出 \(\sum jf_{n,j}\),考虑令 \(g_n=\sum jf_{n,j}\),即将贡献放到状态定义,然后对 \(g\) 转移。
此类 DP 的转移方程为 \(权值和_i=权值和_{i-1}\times 不做要求的方案数+这一位的权值\times 产生权值的方案数\)。
带入,\(g_n=mg_{n-1}+1\times \sum jf_{n-1,j-1}=mg_{n-1}+\sum (j-1)f_{n-1,j-1}+\sum f_{n-1,j-1}\)。
由于 \(\sum f_{n,j}=m^n\),可将转移化简为 \(g_n=(m+1)g_{n-1}+m^{n-1}\),通项公式是等比数列求和,可以快速计算。
当 \(n>m\) 时,对于前 \(m\) 个位置沿用刚才的做法。
考虑 \([i-cnt,i]\) 超出的部分,在 \(cnt>n-m\) 时超出的部分为 \(i-m\),有 DP 转移方程:
设 \(g'_n=\sum jf'_{n,j}\),与上面同理可求 \(g\) 的转移。
现在问题是 \(cnt\leq n-m\),这是可以暴力 DP 的,我们考虑特殊处理。
具体地求出 \(g_m\) 与 \(\sum\limits_{i=0}^{n-m}if_{m,i}\),记 \(w=g_m-\sum\limits_{i=0}^{n-m} if_{m,i}\),将 \(w\) 作为 \(g'\) 的初值跑 \(g'\) 的 DP,需要加上 \(f_{i,n-m}\) 的边界转移。然后对 \(f_{m,0\sim n-m}\),直接暴力 DP 推到 \(f_{n,*}\)。
具体地,定义 \(G_0=\sum\limits_{j>n-m}f_{i,j}\),\(G_1=\sum\limits_{j>n-m}jf_{i,j}\),记 \(K=n-m\)。
有转移:
现在唯一没有解决的问题在于求解 \(\sum\limits_{i=0}^{n-m}if_{m,i}\)。
转移方程 \(f_{i,j}\leftarrow jf_{i-1,j-1}+(m-j-1)f_{i-1,j}\),\(f_{0,0}=1\) 存在封闭形式。
将其想象为在平面上走,假设选择了 \(x_1\sim x_k\) 这些点,那么对 \(f_{m,k}\) 的贡献就是 \((m-1)^{x_1-1}\cdot 1\cdot (m-2)^{x_2-x_1-1}\cdot 2\cdots (m-k)^{x_k-x_{k-1}-1}\cdot k\cdot(m-k+1)^{m-x_k-1}\)。
等于 \((m-1)^{x_1-1}\cdot k\cdot (m-2)^{x_2-x_1-1}\cdot (k-1)\cdots (m-k)^{x_k-x_{k-1}-1}\cdot 1\cdot(m-k+1)^{m-x_k-1}\)。
发现这相当于值域是 \(m-1\),长度为 \(m\) 的序列,\([1,x_1-1]\) 有 \(m-1\) 种选法,以此类推。
位置为 \(x_1,x_2,\dots x_k\) 的位置选法乘积为 \(k!\)。将其视为 \(1\sim k\) 的最后一次出现的位置,这样其余位置的权值分配就自洽了。
\(\{x_i\}\) 为 \(1\sim k\) 最后一次出现的位置集合。
因此 \(f_{m,k}\) 等于长为 \(m\),值域 \([1,m-1]\),\(1\sim k\) 都出现过的方案数,进行容斥。
\(f_{m,k}=\sum\limits_{j=0}^{k}(-1)^j\binom{k}{j}(m-1-j)^m\quad (k < m)\)。
\(f_{m,m}=m!\)。
代数推导保平安:对于 \(f_{i,j}\leftarrow G(j)f_{i-1,j-1}+H(j)f_{i-1,j}\),\(f_{0,0}=1\),\(H\) 无相同值,我们有:
证明太复杂了先咕着。
*260122A(欧拉回路刻画边的经过次数序列,分析性质,维护前后缀信息优化计数)
题意
对初始为 \(0\) 序列 \(a\) 进行如下操作:
- 选择 \(s\) 和 \(01\) 串 \(op\),设当前位置 \(pos=s\)。
- 操作 \(|op|\) 次,第 \(i\) 次进行操作 \(a_{pos}\leftarrow a_{pos}+1\),\(pos\leftarrow pos+1-2op_i\)。
- 记最后的 \(pos=t\)。
现在给定最终序列 \(a'\),求有多少种有序二元组 \((s,t)\) 使得存在一种操作能操作出最终序列。
思路
考虑对单个 \((s,t)\) 判断,先走 \(s\to t\),然后再调整路径。
调整类似于将路径某处向外拉伸,其效果是选择一个长为 \(2\) 个区间将 \(a\) 加 \(1\)。
对于 \(O(n^3)\),我们需要给出将相邻两数 \(+1\) 能否得到某个序列的判据。
首先序列和为偶数。
即我们每次操作差分数组 \(b\),将 \(b_i\leftarrow b_i+1\),\(b_{i+2}\leftarrow b_{i+2}-1\)。
相当于每次把一个值往前移动,根据 Hall 定理,相当于奇数项差分数组的任意前缀和 \(\geq 0\),偶数项同理。
拿出奇偶差分数组检验,默认 \(s<t\),最后答案乘以二,再暴力加上 \(s=t\)。
有一堆细节。
- 不是每个位置都能进行操作,进行操作的位置必定和 \([s,t]\) 构成一个连续段,需要先把必须操作的位置操作了。
- 针对第一条,\(s=t\) 中 \(a_s\) 为了和两侧连通可能要用两次。
如果没有细节:
\(s,t\) 不同奇偶相当于对一个序列全 \(>0\) 的后缀求加权和,平凡。
\(s,t\) 同奇偶,则相当于对区间全 \(>0\) 的子区间计数,平凡。
\(O(n)\)。
但是有细节,因此只会 \(O(n^3)\)。
从 \(s\) 到 \(t\),相当于把 \(s\) 到 \(t\) 的路径减去,然后在判断是否存在欧拉回路。
因此考虑度数序列状物,分两侧,记 \(b_i\) 表示 \((i,i+1)\) 边的经过次数,则 \(2a_i=b_{i-1}+b_{i}+[i=s]+[i=t]\)。
\(b\) 合法,当且仅当:
- \(b>0\) 的部分构成连续段。
- \(b_n=0,b_{1\sim n-1}\geq 0\)。
这两个条件是充要的,因为其本质上是存在欧拉路径的判据。
只考虑 \(s\leq t\),另一侧本质相同,放入 \(s,t\) 后要求仍然存在一组满足条件的 \(b\)。
算出前缀 \(b\) 和后缀 \(b\),记作 \(pre,suf\),将一个位置设为 \(s\) 相当于对后缀的加减操作,你要求的是算上影响的 \(pre\) 能和 \(suf\) 对上,由于 \(b_i\) 固定后 \(b_{i+1}\) 就固定了,因此只需要判断 \(1\) 个位置。后缀“对上”这个性质也可以让我们省去判断后缀 \(+-1\) 是否合法。
然后对于其余的限制,全 \(0\) 连续段是好判断的,对 \(suf_i\) 有两种影响(\(1\) 或 \(-1\)),分别记录一下出现次数,然后遇到 \(b=0\) 就清零次数即可。
*260122B(ACAM fail 上建立虚树)
题意
给定 \(n\) 个字符串 \(S_i\),记 \(p_{i,j}\) 表示 \(S_i\) 在 \(S_j\) 中的出现次数。
给定一个长度为 \(q\) 的数组 \(k_i\),对每个 \(i\) 求所有 \(p\) 的第 \(k_i\) 大。
\(n,q\leq 5.5\times 10^5\),\(\sum len\leq 5\times 10^6\)。
4s,2GB。
思路
关心的是 \(p\) 的桶。
建立 ACAM,枚举 \(S_j\),将 \(S_j\) 经过节点染黑,相当于对每个 \(S_i\) 求 \(S_i\) 的结尾节点子树中有多少个黑点。
把 \(S_j\) 在 ACAM 上跑一遍得到 \(|S_j|\) 个点,用这些点建立虚树,那么对于虚树上每条边,其边上每个点子树中的黑点数一样,批量统计即可。
复杂度 \(O(L\log L)\)。
*[ARC141F] Well-defined Abbreviation(增量维护思想)
题意
给定 \(N\) 个大写字母字符串 \(S_i\ (1\leq i\leq N)\)。
对于字符串 \(T\),定义如下操作:
- 重复以下操作,直到没有任何 \(S_i\) 是 \(T\) 的子串为止:
- 任选一个 \(S_i\),以及 \(T\) 中包含 \(S_i\) 的一个位置,将该位置的 \(S_i\) 从 \(T\) 中删除,并将前后部分连接起来。
如果存在某个 \(T\),使得经过上述操作后可以得到多个不同的结果字符串,则称 \(T\) 为“坏字符串”。请判断是否存在“坏字符串”。
\(1\leq N\leq 10^6\),\(1\leq |S_i|\leq 2\times 10^6\),\(|S_1|+|S_2|+\dots+|S_N|\leq 2\times 10^6\),若 \(i\neq j\),则 \(S_i\neq S_j\)。
题解
尝试从特殊情况入手,不合法的最后一步必定形如 \(AB,BC\) 串或者有子串关系的串。
显然直接判断是不必要的,问题如下:
- 若 \(S\) 是 \(T\) 的子串,但是 \(T\) 可以被其他串消去,则合法。
- 若 \(S\) 是 \(T\) 的子串,\(T\) 可以被其他串消去,也存在一种方案使得 \(T\) 不被消去,必定不合法。
对于 \(AB,BC\) 的结构,\(T=ABC\) 不一定不合法,可能存在一个串是 \(A\) 的子串,从而将 \(A\) 消为 \(C\)。还可能有更复杂的情况。
因此简单的进行判断是不正确的,对于这种逻辑复杂且可能成环的问题,考虑按某个顺序增量维护,并简化限制,容易简化的是子串关系限制,我们按长度从小到大加入串,并假设之前的串合法。
设加入串为 \(s\),之前的集合为 \(S\)。
- \(S\) 合法,所以 \(S\) 消 \(s\) 的方案唯一。
- 使用 \(S\) 消 \(s\),若 \(S\) 存在一个数是 \(s\) 的子串,那么 \(s\) 必须被删空,否则不合法。
- 若 \(S\) 不存在一个数是 \(s\) 的子串,将 \(s\) 加入 \(S\),并判断 \(S\) 的合法性。
对于合法性的判断,我们要做的事情是对没有子串关系的集合进行判断,此时讨论不合法的最后一步,若存在 \(AB,BC\) 则不合法,否则合法。
因此,我们的流程是:
- 按顺序加入字符串。
- 若当前字符串 \(s\) 能被其余字符串消去,则删除当前字符串。
- 否则,若存在字符串是 \(s\) 的子串,则不合法;若存在字符串与 \(s\) 构成 \(AB,BC\) 形式,不合法。其余情况继续。
由于之前维护的 \(S\) 保证消除方式唯一,判断能否被消去直接贪心就是对的。由于大串不能消小串,因此可以先将所有串建 ACAM 解决这部分。
判合法可以枚举 \(B\),使用字符串哈希完成。
一个不使用哈希的 \(100\%\) 做法是,建立 ACAM,\(AB\) 一定在 \(B\) 的 fail 树子树内,\(BC\) 一定在 \(B\) 的 trie 树子树内,\(B\) 可枚举,将结尾位置拿出来跑二维数点,判断一个矩形内是否有超过两个点即可。
260123A(分析性质,01-Trie 上 DP,动态更新 DP 值)
题意
对于 \(S\) 为自然数集的一个子集,定义 \(c\) 为集合 \(S\) 的保序数当且仅当:
给定一个集合 \(T\) 和一个正整数 \(n\),定义 \(U = \{x\in N|0\le x \le 2^n-1 \}\)
对于 \(0 \sim 2^n-1\) 的每个数 \(x\),求有多少个集合 \(S\),满足 $T \subseteq S \subseteq U $,且 \(x\) 为 \(S\) 的保序数,对 \(10^9+7\) 取模。
\(n\leq 18\)。
题解
\(c\) 的第 \(i\) 位是 \(1\),相当于要求不能存在两个串 \(\text{lcp}=i\),使用 01-trie 刻画 LCP,限制形如两个子树不能同时选择。
然后进行 01-Trie 上 DP 即可做到 \(O(2^{2n})\),因为要枚举每个 \(c\)。
考虑动态更新可能变化的 DP 值,\(c\) 的一位翻转时,我们只需要更新 01-Trie 的一个前缀树,\(c\) 的第 \(i\) 位翻转的更新代价为 \(O(2^{n-1-i})\),因此我们希望低位翻转次数少,因此在二进制意义下倒着枚举 \(c\)(\(0000,1000,0100,1100,0010,\dots\)),这样第 \(i\) 位反转次数为 \(2^i\),复杂度 \(O(\sum\limits_{0\leq i\leq n-1} 2^i2^{n-1-i})=O(n2^n)\)。
*260123B(分析最优解形态,逆序对增量,bit 二分,猜结论)
题意
给定一个圆排列 \(a\),求最小进行多少次相邻元素交换,使得圆排列有序。
有序的定义是 \(\forall 1\leq i,j\leq n,(a_i-i+n)\bmod n=(a_j-j+n)\bmod n\)。
\(1\leq n\leq 10^6\)。
题解
考虑枚举循环位移,这样会出的问题是可能存在一些数从末尾交换到开头。
考虑分析最优解形态,其必定是存在一个 \(k\),将 \(k\) 个大数交换到开头,\(k\) 个小数交换到末尾,然后大数和小数之间完成跨分割点的交换,最后加上剩余的逆序对数。
具体地,换的方式是先把这些数换到最前和最后,然后交换头和尾,之后把交换后的数字往中间移动,使得剩余所选大数和小数仍然在边界。
考虑对每个位置算出选定他交换到开头和末尾,然后执行头尾交换后对逆序对个数的影响。
对于一个 \(a_i\),可以算出其【参与小数交换】和【参与大数交换】对逆序对个数的影响 \(p_i,q_i\)。
若 \(i<j,a_i>a_j\),那么 \(a_j\) 被选后 \(a_i\) 必定被选择,因此逆序对个数增量是好算的。
具体地,交换头和尾带来的影响是 \(2(a_n-a_1)-1\),加上头尾的一次交换次数,总影响为 \(2a_n-2a_1\)。
则有 \(p_i=-2a_i+i\),\(q_i=2a_i+n-i\),将与 \(k\) 有关的数分离,最后计算。这里直接加距离的原因是,若 \(a_i\) 去头部,则比 \(a_i\) 大的数也去头部,因此这样多算的量是一个与 \(k\) 有关的等差数列求和。
由于本身交换到头尾也要步数,\(p_i\leftarrow p_i+i,q_i\leftarrow q_i+(n-i)\),原因与上同理。
\(q\) 分离 \(n\) 后的形式是 \(-p\),因此记 \(p_i=2i-2a_i\),最终逆序对可以表示为 \(curInv+\sum\limits_{i\in small} p_i-\sum\limits_{j\in big} p_j+f(n,k)\)。多算的等差数列求和直接抵消了,\(f(n,k)=2nk\),表示分离出的 \(n\)。
那么相当于选 \(p\) 的前 \(k\) 小和前 \(k\) 大,直接排序即可 \(O(n^2\log n)\)。
断环成链,进行滑动窗口的过程,每次移位,对 \(p,q\) 会有修改,修改就是简单的区间加 \(1\)。然后进行头部和尾部的特殊处理。
还是由于加减可以抵消,不用处理区间加,每次对 \(p\) 的修改量为 \(O(1)\),具体地头部的 \(p\) 会移动到尾部并增加 \((2n-2)\),其余的 \(p\) 减少 \(2\),为了保证相对大小不变,将 \(p_{fr}\) 增加 \(2n\) 即可。
可以使用 DS 维护 \(p,q\),每次进行二分,复杂度双 \(\log\)。
注意到每次循环移位时,\(k\) 只会变化 \(O(1)\),其原因是每次至多会让每个类别(分为原来的大数、不进行头尾交换的数、原来的小数)的一个数选择改变,因此暴力移动 \(k\) 即可。
需要支持动态插入删除,求前 \(k\) 小的和,可以使用 bit 上二分,维护值域 bit 记录出现次数与对应的和。
复杂度 \(O(n\log n)\)。
代码通过,但是可能存在问题:
- 我们假设 \(a_1,a_n\) 交换后总能通过若干次使逆序对减少的交换,将需要进行下一个首位交换的数字换到 \(a_1,a_n\) 的位置。
- 但是假如 \(n\) 被首位交换放到的最后,那么 \(n\) 再进行交换显然会错。
upd:但是 \(n\) 向前换能被 \(p\) 算到,再向后换是逆序对能算到的。没有问题。
现在需要解决的问题是不存在 \(a_i>a_j,i<j\),\(a_i\) 向后首位交换,\(a_j\) 向前首位交换。看起来是显然的,证明先咕咕咕。
*P6628 [省选联考 2020 B 卷] 丁香之路 紫(欧拉回路,MST)
题意
有一张 \(n\) 个顶点的无向图。对于任意两个不同顶点 \(i, j\),它们之间有一条需要花费 \(|i - j|\) 单位时间通过的无向边。有 \(m\) 条道路上开有丁香花。
给定 \(s\),对每个 \(1\leq t\leq n\) 的 \(i\) 求出他最少花费多少单位时间从 \(s\) 开始,在 \(t\) 结束,且经过了所有开有丁香花的 \(m\) 条道路。
\(1\leq n\leq 2500\)。
题解
欧拉回路可以刻画每个边的经过次数,并判断合法性。
对于 \(s\neq t\) 的情况,添加边 \((t,s)\) 可以转为求 \(s\) 开始的欧拉回路。
相当于要求 \(m\) 条边至少被经过一次,将这些边先连接上,然后原图是若干个连通块。
如果度数都是偶数,那么求出连通块间的 MST,然后在 MST 上 DFS 遍历即可,因为这里的欧拉回路允许重边,因此只需要管相邻编号的边。
如果有奇度数点,这样的点必为偶数个,考虑按编号两两配对,但是直接连接是不对的,如果 \(x,y\) 配对,正确的做法是将 \(x,x+1,\dots y\) 的相邻点加一个边,因为这样能最小化求 MST 时加的边数。
然后就是只用考虑相邻点的 MST,注意需要忽略度数为 \(0\) 的孤点。
由于每个边经过次数确定时答案已经确定,因此贪心是正确的。
*QOJ833. Cells Blocking(网格图路径偏序结论,通过对角线找路径)
题意
给定 \(n\times m\) 的网格,有些点已经被删去,求有多少种删去两个点的方案使得 \((1,1),(n,m)\) 不连通。
\(1\leq n,m\leq 3000\)。
题解
一开始尝试了 DP,但是发现路径回退比较复杂。
经典结论:存在路径偏序所有路径。
证明是容易的。
这样找出最靠下和最靠右的路径,删除一个点的方案就是路径交集大小。
处理 \(p_{i,j},q_{i,j}\) 分别表示 \((i,j)\) 能否到 \((n,m)\)、能否从 \((1,1)\) 走到。
这样可以贪心求得最靠下和最靠右的路径。
对于本题,考虑枚举一个点 \(t\),这个点必定在最靠下的路径上,然后只要我们能以 \(O(n+m)\) 的代价求出新的最靠下路径,就可以求出新路径和最靠右路径的交集大小,就可以在 \(O((n+m)^2)\) 的复杂度解决问题。
直接回退原来的最靠下路径会有问题,我们再往后走的时候不确定能否经过这个点。
但是能确定的是,在原路径经过点 \(t\) 的时刻 \(tm\),新路径必定不过 \(t\),因此枚举新路径 \(tm\) 时刻经过了那个点,这个点必定在 \(t\) 所在的对角线上,枚举对角线上的点 \(r\),满足 \(p_rq_r\neq 0\),然后贪心往两边找即可求得新路径。
还是由于经典结论,正着贪和反着贪都是对的。
*260123C/QOJ8059. Circular Route(欧拉回路,分治求解动态 MST)
题意
你是一名巴士司机,你每天都在一条环形道路上开巴士。你的巴士很特殊,每个时刻仅能承载一人。你有若干个任务,你要从 $ s_i $ 把一个人接到 $ t_i $,一个人到目的地之前不能下车,到达 \(t\) 时刻立即下车(即可以从 \(t_i\) 接新的人)。
道路是一个 $ 0 \sim L-1 $ 的环,相邻两个点的路程为 \(1\),你的车会不断地绕环顺序行驶直到完成所有任务,任务之间没有顺序要求。
\(q\) 次询问,每次给定起点,问完成任务的最短路程是多少?
\(n,m\leq 200000\),\(L\leq 10^9\)。
题解
考虑判定性问题,二分答案,判定一个答案是否可行。
相当于指定了每条边的经过次数。对于 \((s_i,t_i)\),新加入边 \((s_i,t_i)\),然后将 \(s_i,t_i\) 之间的边经过次数减一,求是否存在欧拉路径。
由于独特的建图方式,欧拉路径如果存在则路径必为绕环走(正反走没有区别),且加入边 \((s_i,t_i)\) 的操作不会改变出入度之差。
因此,只需判断连通性即可,即起点、终点、所有 \((s_i,t_i)\) 是否弱连通。
严谨的,我们可以求出每个弧段 \(e\) 被任务覆盖的次数 \(c_e\),给定总路程 \(D\),我们可以求出弧 \(e\) 被经过的次数 \(k_e(D,S)\),加入任务边 \((s_i,t_i)\),对每个 \((i,i+1)\) 的弧段加入 \(k_e(D,S)-c_e\) 条边,判欧拉路径。
对于多组询问,不能直接二分,整体二分也不好维护。
考虑离散化后对 \(2n\) 个点预处理出答案,然后处理询问是容易的。
连通性即这 \(2n\) 个点连通,边分为两类:
- \((s_i,t_i)\) 的任务边。
- 环上相邻点之间的边。
我们对于第二类边,处理出其被加入的最早时间(即经过次数 \(\neq 0\) 的最早时间),然后跑 MST 即可。
具体地,我们严谨描述一个暴力算法。对于第二类边 \(e\),记 \(c_e\) 表示边 \(e\) 被任务边覆盖的次数,\(k_e(D,S)\) 表示在 \(S\) 作为起点、路程为 \(D\) 的情况下,\(e\) 被经过的次数。则有:
为了避免全部是第二类边,最后没有走完某个任务的情况,还需要保证:
表示每个任务都要做完。
我们发现我们不好处理 \(w_e(S)\) 的变化,考虑维护相对大小,起点往前变化时,直接把扫过的边加上 \(L\),这样边之间相对大小不变。
一个好的理解方式是记 \(res_i\) 表示从 \(1\) 开始,到 \(i\) 之前不做任务,从 \(i\) 开始做任务的答案。
询问时相当于枚举第一个做任务的点,由于 \(res_i\) 没有强制要求 \(i\) 立刻做任务,因此取环上后继就是对的。
现在的唯一问题是如何求 MST。
按照时间轴分治,发现当开始做任务的点从 \(i\) 移动到 \(i+1\) 时,中间这个边的边权会修改,此类 MST 可以分治求解,模板题是 P3206 [HNOI2010] 城市建设。
实际实现的时候,假设初始位于 \(tot\),第一次修改边使起点移动到 \(1\),然后每次修改会把起点往后移动。
我赛时认为答案就是 \(\max_e \{L(c_e-1)+\text{dis}(S,e)\}\),但是这样不能保证连通性,假如 \(L=4\),任务 \((0,2)(2,0)(1,3)(3,1)\),按照这么算是 \(8\),但此时图不连通,也就不存在欧拉路径。
*CF1542E2 Abnormal Permutation Pairs (hard version) *2700(逆序对的独立性质,前缀和优化 DP)
题意
设 \(p\) 和 \(q\) 是 \(1,2,\ldots,n\) 的两个排列。求满足以下条件的排列对 \((p, q)\) 的数量:
- \(p\) 在字典序上小于 \(q\)。
- \(p\) 的逆序对数大于 \(q\) 的逆序对数。
请输出满足条件的排列对的数量,对 \(mod\) 取模。注意,\(mod\) 不一定是质数。\(1\le n\le 500\),\(1\le mod\le 10^9\)。
题解
要求字典序肯定要枚举 LCP,一开始我一直在想,在 LCP 的基础上做插入 DP,但是插入 DP 维护的是相对大小,会破坏 LCP 的相等性质。
逆序对具有良好的性质,假设两个序列前 \(i\) 位的集合相同,那么跨过 \(i\) 的逆序对就是相同的,考虑从这里入手,枚举 LCP 为 \(i\),那么前 \(i\) 位与后 \(n-i\) 位都不用考虑。
为了保证 LCP 相等,确定 LCP 每个数的绝对大小,有一个 \(\frac{n!}{(n-i)!}\) 的系数。
两序列后 \(n-i\) 位构成的集合相同,且 \(p_{i+1}>q_{i+1}\)。需要计算 \(p_{i+1},q_{i+1}\) 对 \([i+2,n]\) 逆序对的贡献,只需决定 \(p,q\) 的 \(i+1\) 位在后 \(n-i\) 位中的排名,记为 \(a,b(a<b)\),那么需要满足 \(a+inv_p<b+inv_q\),\(inv_p\) 表示 \(p\) 后 \(n-i-1\) 位的逆序对。
也即 \(inv_p-inv_q<b-a+1\),令 \(f_{i,j}\) 表示长为 \(i\) 的排列对,逆序对差为 \(j\) 的方案数,求出 \(f\) 就做完了。
直接插入 DP 可以 \(O(n^4)\),式子形如 \(f_{i,j}=\sum\limits_{k=0}^{i} f_{i-1}{j+k}(i-k)+\sum\limits_{k=-i}^{-1} f_{i-1}{j+k}(i+k)\),将系数中与 \(j+k\) 有关的部分分离,可以前缀和优化做到 \(O(n^3)\)。
+CF1809G Prediction *2800(主次依附转移,组合数分配位置,拆组合数阶乘)
题意
给定长为 \(n\) 的数列 \(a\),对满足如下条件的长为 \(n\) 的排列 \(p\) 计数:
- \(\forall 1\leq i<n,|(\max_{j\leq i}a_{p_j})-a_{p_{i+1}}|>k\)。
\(1\leq n\leq 10^6\)。
题解
与 EmotionalFisherman 相似的题,但是还是卡了很久。
将数组排序,记 \(lim_i\) 为最后一个 \(<a_i-k\) 的位置。
考虑主次依附转移,记大于 \(\max\) 的位置为关键位置。
当填入 \(i\) 时,此时 \(lim_i\) 以前的数字不受限制,将其全部填入,因为 \(j\leq lim_i\) 所以 \(j\) 也被填入,此时 \(i\) 的位置必为第一个空位,否则之后位于第一个空位的数字必定位于 \((lim_i,i)\) 之间,不合法。因此无序分配主要元素的位置。
转移 \(j\to i\) 时分配 \(lim_j\sim lim_i\) 之间的位置,因为这些位置的限制不受当前已确定元素约束。
前 \(lim_j\) 个位置和 \(i,j\) 已经填好,因此方案数为 \(\binom{n-lim_j-2}{lim_i-lim_j-1}(lim_i-lim_j-1)!\),即 \(f_i=\sum\limits_{j\leq lim_i} f_j\binom{n-lim_j-2}{lim_i-lim_j-1}(lim_i-lim_j-1)!\)。
拆组合数阶乘,记 \(g_i=(n-lim_i-1)!f_i\),做前缀和优化即可做到 \(O(n)\)。
启示:DP 转移中组合数进行位置分配时,可选择分配当前由受限变为不受限制的元素(本质上是由紧到松),并分析性质。
*[AGC066A] Adjacent Difference(构造,奇偶交替推广,弱化条件思想)
题意
给定一个大小为 \(n\times n\) 的数组 \(A\) 和数字 \(d\) , 和数组中的每个数字 \(A_{i,j}\) , 你可以对每个数字进行加上一个数或减去一个数的操作 , 使得每个数字与其相邻数字的差的绝对值大于等于 \(d\) 。 并且对于每个操作值的绝对值之和不超过 \(\frac{1}{2}dn^2\) 。
$ 2 \leq N \leq 500 \(,\) 1 \leq d \leq 1000 $。
题解
考虑 \(d=1\) 的全 \(01\) 矩阵怎么做,容易发现交替黑白染色,至少一个方案正确。
如果不是 \(01\) 矩阵,按奇偶染色(即将所有数在 \(\bmod 2\) 意义下考虑)也是正确的。
对于 \(d>1\),考虑推广刚才的结论,定义【奇】数为 \(\bmod 2d=d\) 的数,偶数为 \(\bmod 2d=0\) 的数,将所有数在 \(\bmod 2d\) 意义下考虑,则 \(0,d\) 交替染色方案中必有一个方案正确。
*QOJ 970. Best Subsequence(和不超过 \(x\) 按 \(\frac{x}{2}\) 分类,最优解的偏序性质,拆点贡献)
题意
有一个长度为 $ m $ 的序列 $ A $,进行 $ q $ 次询问。每次询问给定 $ l, r, k $,要求从 $ A[l, r] $ 中选出一个长度恰好为 $ k $ 的子序列 $ C $,使得 $ C $ 中相邻两项(包括首尾相邻)之和的最大值最小,你只需输出这个最小值即可。
$ m, q \leq 10^5, \quad 0 \leq A_i \leq 10^9 $。
题解
考虑什么样的数放一起和不超过 \(x\),一个思考方式是将其连边,对于 \(\leq \frac{x}{2}\) 的数的导出子图为完全图,对于 \(>\frac{x}{2}\) 的数的导出子图为若干孤点。
二分答案 \(x\),按 \(\frac{x}{2}\) 分类,最优解肯定选满 \(\leq \frac{x}{2}\) 的数字,然后如果两个相邻的 \(\leq \frac{x}{2}\) 的数字 \(p,q\) 中,存在 \(\leq x-max(p,q)\) 的数字,就选上。
由于牺牲小数选择大数必定不优(可以通过调整法证明),因此这样的贪心是正确的。
考虑数据结构优化,选满 \(\leq \frac{x}{2}\) 的数字,然后查询每对相邻数之间的最小值是否 \(\leq x-\max(p,q)\)。
考虑整体二分,需要动态维护这个过程,查询是区间 $\leq $ 某个数的个数,不能 \(\text{poly}\log\)。
整体二分的本质是维护从小到大加入 \(a_i\) 的过程,考虑直接进行这个过程,并使用主席树进行可持久化。
从小到大加入 \(a_i\),记 \(a_i\) 的前驱和后继为 \(p,q\),则当 \(x\geq \max(p,q)+a_i\) 时 \(a_i\) 会被选入,当 \(x\geq 2a_i\) 时 \(a_i\) 会被当做大数选入。
因此 \(a_i\) 被选入对应的答案是一个形如 \([t,+\infin]\) 的区间,将所有 \(t\) 离散化后容易使用主席树维护。
查询直接二分 \(x\),找到区间第一个 \(\leq \frac{x}{2}\) 的数 \(L\) 和最后一个 \(\leq \frac{x}{2}\) 的数 \(R\),在主席树查 \([L,R]\) 在 \(x\) 版本的答案,并使用 RMQ 单独处理头尾能否多选一个数字即可。
其实整体二分也能做,先处理出每个 \(t\) 就能做了,但是意识到这一点就没必要整体二分了。
启示:
在进行整体二分前先思考从小到大加入数字并离线回答二分的 check 怎么做。这一定是不强于整体二分的。
单组询问可二分,解决多组询问的另一个思路是:尝试拆点贡献,即每个点在答案满足什么条件的时候有贡献,之后使用主席树维护。
*QOJ 1351. Koosaga's Problem(DFS 树,异或哈希判二分图)
题意
给定一张简单连通无向图,求有多少边集 \(X\) 满足:
- 删去 \(X\) 后,图是二分图。
- \(|X|\leq 2\)。
- 不存在边集 \(Y\),满足 \(|Y|<|X|\),且满足上述两个条件。
\(1\leq n,m\leq 2.5\times 10^5\)。
题解
考虑建立 DFS 树,是二分图当且仅当所有非树边覆盖的长度 \(+1\) 都是偶数。
将删去一个边视为修改其边权为 \(0\),相当于反转所有覆盖它的非树边的奇偶性。
因此使用异或哈希,对非树边 \((u,v)\),给树上每个 \(u,v\) 之间的边异或上某个随机数 \(w\),然后删两个边合法当且仅当两个边的异或和等于所有奇边的 \(w\)。容易使用 map 维护。
加下来说明将删去一个边视为修改其边权为 \(0\) 是正确的。
-
当这个边不被非树边覆盖时,显然不会影响合法性。
-
当这个边只被偶非树边覆盖时,由于集合具有极小性,因此不会对这个边进行修改。
-
否则删去后 \(u,v\) 必定存在一个长度为偶数的路径,这个在中间加一个 \(0\) 边等价。
*260126A(分析性质,倍增分块,“集合中最小不能被表示出的数”的经典结论)
题意
定义一个可重集的权值为可重集最小不能被表示出的数,即 \(\text{mex}_{T\in S} \sum\limits_{i\in T} S_i\)
给定序列 \(a\),求所有序列所有区间构成可重集的权值之和,对 \(998244353\) 取模。
\(1\leq n\leq 500000\),要求单 \(\log\)。
题解
经典结论:可重集最小不能被表示出的数,为最小的满足 \(\sum [S_i\leq x]S_i<x\) 的数字 \(x\),证明考虑动态维护 \(x\) 的过程,从小到大加入集合中的数字,如果 \(x\geq S_i\) 则 \(x\) 加 \(S_i\),否则答案就是当前 \(x+1\)。
直接维护可以从小到大加数,每个 \(r\) 维护一个 \(l\) 指针,复杂度 \(O(n^2)\)。
对于一个区间,由于断点必定大于之前的和,所以加入一个可能的断点,区间和必定翻倍,因此只有 \(\log\) 个本质不同的断点。
对于来自“至少翻倍”的 \(\log\),可以考虑通过倍增分块实现,具体地,在 \([2^i,2^{i+1})\) 区间中,只可能有一个断点,且断点为 \([2^i,2^{i+1})\) 中的最小数字。
因此答案可以表示为 \(<2^k\) 的数字和 \(+1\),枚举 k,统计可以表示为 \(<2^k\) 的数字和 \(+1\) 的区间贡献。
容易发现区间具有偏序关系,即 \([l,r]\) 的断点大于 \([l,r-1]\),因此若 \([l,r]\) 答案可以表示为 \(<2^k\) 的数字和 \(+1\),则 \([l,r-1]\) 也可以。
因此符合条件的 \(r\) 是一段前缀,双指针即可。需要保证 [l,r] 断点在 2^k 后,因此从小到大枚举 k,只计算新变化的位置。
注意不同 k 之间没有任何单调性。
*260126B(完全背包的分治解法)
题意
解决完全背包最优化计数,物品之间有序(即放入 \(12\) 和放入 \(21\) 算两种方案),\(n,w\leq 2000\),\(v,V\leq 10^9\)。\(w\) 指重量,\(v\) 指价值,\(V\) 指容量。
题解
场上不会 \(O(nV)\),鉴定为没睡醒。
考虑 \(O(nV)\) 怎么做,由于有序,因此不能按下标顺序 DP,用多重集组合数算贡献至少三次方。
考虑每次加入时直接枚举加入哪种物品,来做到“有序”的组合意义,令 \(dp_{i}\) 表示重量和为 \(i\) 的最优价值和与方案数,DP 状态定义为二元组 \((val,cnt)\),状态更新(\(+/\sum/\leftarrow\))定义为 \(val\) 取大的,如果一样就 \(cnt\) 相加。状态拼接($\times $)定义为 \(val\) 相加 \(cnt\) 相乘。
完全背包除了同余最短路外,还有一个解法是分治。
具体地,对于 \(dp_y\),由于有序,必定存在恰好一个物品跨过 \(\frac{y}{2}\)。
有 \(dp_{y}=dp_{x}\times (v_i,1)\times dp_{y-x-w_i}\)(\(x\leq \frac{y}{2},x+w_i>\frac{y}{2}\))。
考虑分治,由于 \(\max w\leq 2000\),记 \(\max w=W\),我们求解 \(V\) 的 DP 值,只需求解 \([\frac{V}{2}-W,\frac{V}{2}]\)。
我们求解 \([L,R]\) 的 DP 值,只需求解 \([\frac{L}{2}-W,\frac{R}{2}]\)。
分治过程形如 \([V,V] \leftarrow [V/2-W,V/2] \leftarrow [V/4-3W/2,V/4]...\),区间长度不超过 2W。
因此每层允许平方,对 \(dp_{y}=dp_{x}\times (v_i,1)\times dp_{y-x-w_i}\) 直接暴力枚举 \(w_i,y,x\) 是三次方的,考虑分步转移,令 \(G_t=\sum dp_{x}\times (v_i,1)\quad (t=x+w_i)\),然后 \(dp_{y}\sum G_{t} \times dp_{y-t}\)。
由于 \(x\leq \frac{y}{2}\),\(t>\frac{y}{2}\),考虑扫描线的思想,从小到大枚举 \(y\),对每个 \(y\),相当于对 \(G\) 新增了 \(dp_{\frac{y}{2}}\),更新 \(G\)。然后枚举 \(t\),用 \(G\) 更新 \(dp\) 即可。
当区间右端点降到可接受范围内暴力,复杂度 \(O(W^2\log V)\)。
*QOJ 8085. Bulbasaur(最大流等于最小割转化,换维 DP)
题意
给定一张 \(n\) 层的分层图,每层恰好有 \(k\) 个节点。这张图上只有相邻层之间上一层连向下层的有向边,连边情况由输入给定。
设从第 \(i\) 层某个节点走到第 \(j\) 层某个节点的路径集合为 \(S_{i,j}\),称两条路径不交当且仅当它们没有公共节点,记 \(f(i,j)\) 为 \(S_{i,j}\) 中最多能选出的两两不交路径数量。求 \(\sum_{1 \leq i < j \leq n} f(i,j)\)。
\(2 \leq n \leq 40000, \quad 1 \leq k \leq 9\),时间限制 6s,空间限制 512MB。
题解
这是一个特殊图最大流问题,直接流不好做,考虑转为最小割,即最少删除的点数。
注意到 \(f(i,j)\leq k\),且 \(f(i,j)\) 有单调性,考虑对于一个 \(j\),枚举答案等于 \(1\sim k\) 的最大 \(i\),设 \(f_{j,c}\) 表示删 \(c\) 个点不能到 \(j\) 的最大 \(i\),只要求出 \(f\) 后答案就能快速求了。
\(k\) 很小考虑状压 DP,删点形如依次从点集中去掉点的过程,因此考查 \(i\) 能否连通 \(j\) 层的某个点集,设 \(g_{S,j,c}\) 表示删 \(c\) 个点只能到 \(j\) 层 \(S\) 中的点最大 \(i\),转移先进行跨层转移,然后依次决定每个点删不删。
复杂度 \(O(nk^22^k)\)。
260127A(构造,调整法)
题意
给一个残缺的树,构造一个完整的树满足直径恰为 \(k\),或报告无解。
\(1\leq n,k\leq 2\times 10^6\),\(0\leq m\leq n-1\)
题解
显然只关心每个连通块的直径,相当于每个连通块是一个链。
最大情况是将所有链拼在一块,最小情况是将最长链方中心,连通块之间连成菊花,从每个链的中间点连出。
考虑从最小情况开始调整,尝试每次调整使得直径最多 \(+1\),且能够从 \(\min k\) 调到 \(\max k\)
先选出若干块作为主干,使得这些块的 \(\sum (len+1) >= k+1\),然后把这些块串一起形成链套单个菊花的局面,再调整,调整就是调整连出边在链上的位置。码量大概 4k。
*260127B/AT_code_festival_final_j 2 Cups(数论,剩余系理论)
题意
给定 \(A,B,K\)。现在有两个空杯子,容量分别为 \(A\) 升和 \(B\) 升。你可以做以下三种操作。
- 将一个杯子的水喝完。
- 将一个杯子中倒满水。
- 从一个杯子 \(p\) 向另一个杯子 \(q\) 中倒水,直到 \(q\) 被装满或 \(p\) 空为止。
有多少个 \(C\) 使得你可以用至多 \(k\) 次操作使某个杯子中有恰好 \(C\) 升水?
\(1\leq A,B\leq 10^{10},0\leq K\leq 10^{10}\)。
部分分:\(A,B\leq 10^6\)。
题解
先将 \(A,B\) 除掉 \(\gcd\),以下默认 \(A,B\) 互质且 \(A<B\)。
考虑暴力,发现除了第一步可以倒满两个杯子中的一个外,每步的转移是唯一的。
以 \(a=3,b=10\) 举例,\((0,0)\to (3,0)\to (0,3)\to (3,3)\to (0,6)\to (3,6)\to (0,9)\to (3,9)\to (2,10)\to (2,0)\to (0,2)\to (3,2)\dots\),先倒大杯同理。
特判 \(k\leq O(1)\),考虑上述过程在干什么,\((0,0)[\to (3,0)\to (0,3)][\to (3,3)\to (0,6)][\to (3,6)\to (0,9)][\to (3,9)\to (2,10)][\to (2,0)\to (0,2)]\to [(3,2)\to (0,5)]\),发现每走两步都能得到一个新东西,且每次走两步相当于将大杯容量在 \(\bmod b\) 意义上加 \(a\)。
有一个例外是大杯满的需要清空大杯,这会消耗两步。
我们得到的第 \(t\) 个新数字就是 \(at\bmod b\),根据剩余系理论,当 \(t\leq b\) 时这些数字不重,否则答案就是 \(b+1\)。
考虑得到第 \(t\) 个新数字的耗时 \(f(t)\),每次倒满时需要额外花费两步,总共倒了 \(at\) 单位的水所以会倒满 \(\lfloor\frac{at}{b}\rfloor\) 次,因此 \(f(t)=2(t+\lfloor\frac{at}{b}\rfloor)\)。
考虑先倒满大杯的过程,发现是一样的,第 \(t\) 个数字为 \(-at\bmod b\),相当于在环上反着走。
\((0,0)\to [(0,10)\to (3,7)][\to (0,7)\to (3,4)][\to (0,4)\to (3,1)][\to (0,1)\to (1,0)][\to (1,10)\to (3,8)]\dots\)。
因此我们只需要二分最大的 \(t\) 使得 \(f(t)\leq k\),答案就是 \(2t+2\),\(+2\) 的原因是需要算上 \(0,b\)。
然后还有一个细节是,先倒小杯的路线在“额外花费两步”的过程中可以获得新的容量,因此二分出的 \(t\) 满足恰好到 \(t+1\) 需要“额外两步”时,即 \(f(t)+2\leq k<f(t+1)\) 时,需要将答案加 \(1\)。
最后将答案与 \(b+1\) 取 \(\min\) 即可。
*260127C/P9099 [PA 2020] Ogromne drzewo(贪心模型,拆贡献,根号结论与根号平衡,多层次推理)
题意
有一棵树,节点有 \(n\) 层。第一层只包含一个节点,表示树的根。每个节点的子节点都只在其下一层,最后一层的节点除外,它们是叶子。对于区间 \([1, n - 1]\) 中的每一个 \(i\),第 \(i\) 层的每个节点都有 \(a_i\) 个子节点。
Algolina 选择了树上的某个节点 \(A\),Byteasar 选择了节点 \(B\)。从 Algolina 开始,他们将轮流对树的节点涂色,Algolina 用红色,Byteasar 用蓝色。在游戏开始时,所有节点都是白色的。每个节点将恰好被涂色一次。
Algolina 获得的分数(用 \(S_A\) 表示)将是所有红色节点到节点 \(A\) 的距离之和,Byteasar 获得的分数(用 \(S_B\) 表示)将是所有蓝色节点到节点 \(B\) 的距离之和。Algolina 的目标是最大化 \(S_A-S_B\) 的值,而 Byteasar 的目标是最小化它。
假设他们都以最优策略进行游戏,计算 \(S_A-S_B\) 对 \(10^9+7\) 取模后的值。
有 \(q\) 组询问,每组询问给定 \(A,B,\text{lca}(A,B)\) 的深度(显然深度确定答案就确定了)。
\(2\le n\le 3\times 10^5\),\(1\le q\le 3\times 10^5\),\(2\le a_i\le 3\times 10^5\),\(1\le W_{\operatorname{lca}(A,B)}\le W_A,W_B\le n\)。
特殊性质 A:满足树最多有 \(3\times 10^5\) 个节点,且 \(q\le 100\)。
题解
Part 1. \(O(nq)\)
设询问中 \(A,B,C=\text{lca}(A,B)\) 的深度分别为 \(x,y,t\)。
定义点 \(i\) 到 \(A\) 的距离为 \(disa_i\),到 \(B\) 的距离为 \(disb_i\)
考虑特殊性质 A 怎么做,贪心策略是每次选择 \(disa_i+disb_i\) 大的点,因此暴力即可。
我们希望求和形式优美,考虑令每个点的初始贡献为 \(\frac{disa-disb}{2}\),这样 \(A\) 选就有额外的 \(\frac{disa+disb}{2}\) 贡献,\(B\) 选有额外的 \(\frac{disa+disb}{2}\) 贡献。
首先需要计算初始贡献,本质是需要对 \(A,B\) 计算所有点到他的距离之和。
距离刻画为 \(dep_u+dep_v-2dep_{\text{lca}}\),预处理 \(sdis_i\) 表示第 \(i\) 层点子树内所有点到它的距离和,\(scnt_i\) 表示第 \(i\) 层子树点个数。然后枚举 \(\text{lca}\),贡献形如 \(scnt+sdis\) 的前缀和,可以轻松做到 \(O(n)\) 预处理 \(O(1)\) 查单个点。
然后考虑 \(\frac{disa+disb}{2}\) 部分,显然不能进行排序,唯一可以进行的操作是统计出现次数,由于贡献是交替求和因此只关心出现次数的奇偶性。
\(\frac{disa+disb}{2}\) 相当于 \(\frac{\text{dis}(a,b)}{2}+dx\),其中 \(dx\) 表示这个点到 \(A-B\) 路径的垂直距离。
因此可以只计算 \(dx\) 的交替和然后通过奇偶性判断是否要加上 \(\text{dis}(a,b)\) 即可。
那么我们要统计每个 \(1\leq dx\leq n\) 的 \(dx\) 的出现次数的奇偶性。
我们记 \(nxt_i\) 表示 \([i,n]\) 中第一个 \(a\) 为偶数的位置。
对于 \(A\) 子树内的点,深度在 \([x,nxt_x]\) 的点有贡献,贡献到 \([0,nxt_x-x]\),\(B\) 子树同理,为 \([0,nxt_y-y]\)。
对于 \(C\) 子树外的点,枚举其和 \(C\) 的 \(\text{lca}\) 的深度 \(d\),这个点本身有 \([t-d,t-d]\) 的贡献,总共是对 \([1,t]\) 的贡献。若 \(a_d\) 为偶数(因为此时刨掉了 \(C\) 所在子树),则对 \([t-d+1,t-d+nxt_{d+1}-d]\) 造成贡献。
对 \(C\) 子树内且不在路径中其他点子树内的点(即 \(C\) 子树刨去 \(0/1/2\) 个子树,\(0/1/2\) 取决于 \(x,y\) 是否等于 \(t\)),若刨去子树后 \(C\) 的子数个数是奇数,对 \([1,nxt_{t+1}-t]\) 造成贡献。
对于和 \(A\) 的 \(\text{lca}\) 在 \(C\) 之下的点,枚举其深度 \(d\),对 \([1,nxt_{d+1}-d]\) 造成贡献。\(B\) 同理。
对路径上的点(不含 \(A,B\)),贡献到 \([0,0]\)。
因此我们有 \(O(nq)\) 做法,直接暴力进行上述操作,操作是区间异或 \(1\),差分维护,最后求全局交替和,然后判断 \(\text{dis}(a,b)\) 的系数,最后回带到一开始算答案的式子中。
Part 2. 优化答案计算
记 \(v\) 表示 \(dx\) 的桶。
我们发现算答案时需要遍历整个数组,因此先尝试优化答案计算方式。
因为是交替和,设 \(v\) 中 \(1\) 的位置是 \(p_1>p_2>\dots\),则答案为 \(p_1-p_2+p_3-p_4+\dots=\sum\limits_i (p_{2i-1}-p_{2i})\)。
关键转化:为 \(1\) 的位置下标交替求和,可以转为对序列做后缀异或和后求 \(1\) 的个数。
那么我们的区间修改对后缀异或和的影响是 \(r,r-2,r-4,\dots\) 翻转,\(l-1,l-3,l-5,\dots\) 翻转。
对序列奇偶拆分,相当于前缀异或,求全局 \(1\) 个数。
Part 3. 优化区间操作
现在考虑如何优化区间操作,我们需要优化如下操作:
- \([0,nxt_x-x],[0,nxt_y-y],[1,t],[1,nxt_{t+1},t],[0,0]\) 等 \(O(1)\) 次的操作。
- 对每个 \(1\leq d<t\),若 \(a_d\) 为偶,修改区间 \([t-d+1,t-d+nxt_{d+1}-d]\)。
- 对每个 \(t< d\leq x\),修改区间 \([1,nxt_{d+1}-d]\)。对每个 \(t<d\leq y\),修改区间 \([1,nxt_{d+1}-d]\)。
第一类可暴力。
第二类限制形如 \(d<t\),因此考虑离线按 \(t\) 从小到大加入询问,由于修改区间和 \(t\) 有关,因此将修改区间平移为 \([n-d+1,n-d+nxt_{d+1}-d]\)(注意所有操作要跟着平移,且计算答案时需要补回这部分贡献)。第三类限制本来就有 \(t\),所以平移后不会有太大影响。
第三类平移后为对于 \(d\in [t+1,x]\) 且 \(a_d\) 为偶数的 \(d\),操作 \([n-t+1,n-t+nxt_{d+1}-d]\)。
如果区间没有性质则不可优化,分析区间性质,由于 \(a_d\) 为偶数,又因为 \(nxt_{d+1}-d\) 表示下一个 \(a\) 为偶数的位置,因此这类询问有 \(\sum (nxt_{d+1}-d)\leq n\),即本质不同的操作区间只有 \(O(\sqrt n)\) 个。
只需预处理每个前缀的 \(nxt_{d+1}-d\) 的所有不同取值出现次数奇偶性,进行第三类修改时拿出 \(x\) 前缀和 \(t\) 前缀做类似异或的操作即可,具体地就是归并数组并找出出现奇数次的数进行操作。
这样我们需要维护一个数据结构,支持 \(O(n\sqrt n)\) 次区间异或,\(O(n)\) 次全局查 \(1\) 的个数,那么需要做到 \(O(1)-O(\sqrt n)\)。
Part 4. 最后的优化
事实上并不存在这样的数据结构(最优解法是线段树,\(O(n\sqrt n\log n)\))。考虑继续分析性质,修改的瓶颈在于第三类操作,注意到第三类操作的左端点一致,且需要撤销。因此尝试用其他方法代替修改。具体地,假设修改为 \([l,p_1],[l,p_2],\dots\),其中 \(p_1>p_2>\dots\),那么放到前缀操作上,有 \([1,l],[1,p_1],[1,p_2],\dots\) 翻转,可以发现这相当于 \([p_2,p_1],[p_4,p_3],\dots\) 翻转。
区间不交,因此可以不进行实际修改,通过查询区间中有多少个 \(1\) 来得知修改对答案的变化量。
因此我们需要维护一个数据结构,支持 \(O(n)\) 次区间异或,\(O(n\sqrt n)\) 次区间查 \(1\) 的个数,显然可以序列分块做到 \(O(\sqrt n)-O(1)\)。
(代码先咕咕咕)
CF62E World Evil *2700(特殊图最大流,最大流等于最小割转化,状压 DP)
题意
给定一个分层图,每层 \(n\) 个点,共 \(m\) 层。相邻层之间编号相同的点有连边,同层中点按标号顺序连城一个环。
给定每个边的边权,将 \(S\) 与第一层所有点连边,\(T\) 与最后一层所有点连边,求最大流。
所有边都是无向边,\(2\leq n\leq 5\),\(2\leq m\leq 10^5\)。
题解
直接跑最大流肯定过不了。
对于有特殊性质的图的最大流问题,可以考虑转为最小割,这样的好处是最小割可以通过多种方式(例如 DP)解决从而避免跑最大流算法。
转为最小割,由于 \(n\leq 5\) 考虑状压 DP,考虑一个点集能否到第 \(m\) 层,令 \(f_{i,S}\) 表示第 \(i\) 层只有 \(S\) 与最后一层连通的最小割,转移分两步:决策环上边删不删和决定跨层边删不删。
预处理 \(to_{s,d}\) 表示点集 \(s\) 在删除环上边集 \(d\) 后能到达的同层点集,可以做到 \(O(2^{2n}m)\)。
bonus:进行分步转移可以优化到 \(O(n2^nm)\),可类比 FMT。
upd:这个做法假了,原因是流可以倒着走。
考虑直接对着最小割定义 DP,\(f_{i,S}\) 表示 \(i\) 到 \(m\),\(S\) 属于原点的答案。
当所有属于源点和属于汇点之间的边都断开时,是一个合法的割。
我们无需保证割两侧内部的连通性,因为多割边一定不优。
转移时对于环上边,若连接的两个点不同时属于源点或汇点,则断边。然后枚举下一层的 \(S'\),如果 \(S'_j\neq S_j\),则断掉跨层边 \(j\)。
这样我们 DP 出的解严格符合最小割定义,不会出问题。
仍然使用类似 FMT 的技巧做到 \(O(n2^nm)\),删掉第 \(i\) 行的跨层边代表第 \(i\) 行被阻断。
*CF1508F Optimal Encoding *3500(DAG 最小表示,拆元素对时间轴的贡献区间,二维数点,回滚莫队/不加入莫队理论,带修 ST 表结论,单点修区间 \(\max\) 根号平衡方式)
题意
给定一个 \(1 \sim n\) 的排列 \(a_1, a_2, \dots, a_n\),以及 \(q\) 个区间 \([l_1, r_1], [l_2, r_2], \dots, [l_q, r_q]\)。
定义:
- 排列 \(b_1, b_2, \dots, b_n\) 对一个区间 \([l', r']\) 保序,当且仅当对任意 \(l' \le x < y \le r'\),\([a_x < a_y] = [b_x < b_y]\)(即 \(a\) 和 \(b\) 在该区间内的相对大小关系完全相同)。
- 排列 \(b\) 是 \(k\)-相似的,当且仅当 \(b\) 对所有区间 \([l_i, r_i]\)(\(1 \le i \le k\))保序。
- 一个有向无环图(DAG)称为 \(k\)-相似排列的编码,当且仅当其所有拓扑序与所有 \(k\)-相似排列一一对应。
对于每个 \(k = 1, 2, \dots, q\),求对 \(k\)-相似排列的编码的最少边数。
\(n \le 2.5 \times 10^4\),\(q \le 10^5\),七秒时限。
题解
考虑 DAG 最小表示的做法,若存在路径 \(u\to x_1\to x_2\to \dots\to v\),则 \(u\to v\) 的边可删除。
考虑一个暴力,对每个区间按 \(a\) 大小排序连成一个链,然后对这若干个链的并做最小表示。
分析存在 \(u\to v,u\to x_1\to x_2\to \dots\to v\) 的条件,出现这样路径的充要条件是:
- 不存在 \(w\in [\min(u,v),\max(u,v)]\),满足 \(a_u<a_w<a_v\)。
- 记 \(w_1\) 为 \(\min(u,v)\) 左边满足 \(a_u<a_{w_1}<a_v\) 的最大 \(w_1\),同理找到和 \(v\) 右边最小的 \(w_2\)。存在一个区间包含 \(u,v\) 且不含 \(w_1,w_2\)、存在另一个区间包含 \(u,v\) 且包含 \(w_1,w_2\) 中至少一个。
相当于区间满足某些限制时 \(u,v\) 的边会被删除,题目要求按时间顺序加入区间,因此考虑每个连边对时间轴的贡献。
上述条件即当 \(u,v\) 中间存在 \(a_u<a_w<a_v\),那么 \(u,v\) 始终不存在边,否则找到 \(u\) 左边最大的 \(w_1\) 和 \(v\) 右边最小的 \(w_2\),则当存在区间包含 \(a_u,a_v\) 时,\((u,v)\) 出现,当区间包含 \([w_1,v]\) 或 \([u,w_2]\) 时边 \((u,v)\) 消失。
暴力将所有边找出进行二维数点即可,可使用根号平衡做到 \(O(n^2+q\sqrt{n})\)。
关键观察:有用的边数是根号级别的。
具体地对区间跑回滚莫队,实时维护 \(a\) 按大小连边的链,只有这些边是有用的。
因此使用普通莫队即可做到 \(O(q\sqrt n\log n)\),由于维护的是链表,删除比插入容易,因此使用不加入莫队可以做到 \(O(q\sqrt n)\)。
找出 \(O(q\sqrt n)\) 条边后做和上面相同的事情即可。
然后需要解决快速查找 \(w_1,w_2\),按 \(u\) 扫描线转为单点修改区间 \(\max\)。可以使用分块套 ST 表,ST 表有经典结论:修改一个位置影响的信息量为 \(O(n)\),因此可以做到 \(O(\sqrt n)-O(1)\)。
偷懒写高复杂度做法了(逃。
\(O(n^2)\) 的话,直接实现空间复杂度是爆炸的,需要再分析一些东西。
发现按上述方案连边,一个点向左侧连的边,只会连接被询问覆盖的点中,左侧值最靠近它的两个点。右侧同理。因此每个点维护被询问覆盖的两个指针,然后动态更新最近值匹配点即可。
注意“值最靠近它的两个点”的关系不是双向的,即【\(a\) 是 \(b\) 左侧值最近的点】与【\(b\) 是 \(a\) 右侧值最近的点】不等价,因此需要判断只计入双向贡献。容易说明这样的边是必要的,因此这个刻画充要。
启示:不管时间超限还是空间超限都要先分析性质,最后在思考如何除 \(w\) 或卡常。
*QOJ 977. Local Maxima(二项式反演,树的拓扑序计数,计数转概率)
题意
计数以下 \(n\times m\) 的矩形个数对给定质数 \(P\) 取模的结果。
- \(1\sim n\times m\) 每个数恰好出现一次。
- 恰好有一个位置,使得它所在的行和列不存在大于它的数。
\(1\leq n,m\leq 3000\)。
题解
\(n\times m\) 一定是唯一的位置,考虑先放入这个位置,然后往外拓展。
从大到小填入数字相当于一个扩展骨架的过程,能填入的位置始终是若干个横线和竖线的并。
由于加入一个数是否扩大骨架是未知的,考虑批量操作不确定的部分,每次新加入行需要一次性将行填满,这样只需记录骨架大小。
系数是组合数乘阶乘的形式,直接 DP 即可。
另一个做法是考虑容斥,记 \(f_i\) 为钦定 \(i\) 个数满足这个条件,\(g_i\) 为恰好。
则 \(g_1=\sum\limits_{j=1} (-1)^{j-1}\binom{j}{1}f_j\)。
求 \(f\) 相当于限制一个数大于它所在的一横一竖,注意到选的这些数必定不同行也不同列,因此这些数的大小关系确定后方案数是树的拓扑序计数,这是容易的。另一个思考过程是考虑转概率,最大值必定在被选择的位置之一,放置最大值后递归进入子问题。
*P7650 [BalticOI 2007] Ranklist Sorting (Day 1)(相对坐标与绝对坐标转化,贡献提前计算技巧)
题意
给定一个排列 \(a\),将其进行若干次插入排序后变为 \(1\sim n\) 的排列,从 \(i\) 抽出一个数插入 \(j\) 的代价是 \(i+j\)。
构造操作代价和最少的操作方案。
\(1\leq n\leq 2000\)。
题解
先考虑固定一些东西,我们断言:
- 必定存在一个最优解按顺序 \(n\to 1\) 操作。
因此操作顺序是固定的,考虑从大到小进行操作,操作 \(i\) 时,\(i+1\sim n\) 的相对顺序已经正确,\(\leq i\) 的数相对大小不变。
我们需要求出 \(i\) 的绝对下标,这在 \(i+1\sim n\) 已经被操作过的局面下是比较困难的。
我们发现如果 \(x\) 接到 \(y\) 前面那么 \(xy\) 之后不会分开,因此可以考虑进行如下转化:
- 将 \(x\) 接到 \(y\) 前视为 \(xy\) 共用一个格子。
即:
对移动情况进行分类,有序被判定为所有 \(i\) 接到了 \(i+1\) 之前,\(i\) 的移动有两种情况:
- \(i\) 主动移动到 \(i+1\) 前。
- \(i\) 不动,让 \(i\sim i+1\) 之间的数字移出(只有 \(i\) 在 \(i+1\) 左侧才能这么干)
不动的情况不好处理,先考虑只有主动移动的情况。
那么此时 \(i+1\sim n\) 必定被移到最后一格,那么 \(i\) 的绝对下标就是前面比它小的数字个数。
令 \(f_i\) 表示操作到 \(i\) 的最小代价,\(pos_i\) 表示 \(i\) 的初始下标,则:
现在考虑不动的情况。
此时需要二维状态,记录 \(i\) 被换到了位置 \(j\)。
此时需要先修正主动移动,将主动移动的转移改为 \(f_{i,p}=f_{i+1,p}+\sum\limits_{j=1}^{pos_{i}-1}[a_j<i]+\sum\limits_{j=1}^{p-1}[a_j<i]+2\)(需要适应 \(i\) 在 \(i+1\) 右侧)。
不移动即 \(f_{i,pos_i}\leftarrow f_{i+1,q}\),考虑贡献提前计算,\(pos_i\sim q\) 之间的数计算时,比 \(i\) 小的数的绝对下标会少算 \(1\),即 \(f_{i,pos_i}\leftarrow f_{i+1,q}+\sum\limits_{j=pos_i+1}^{q-1}[a_j<i]\)。
但是这是错的,Hack:\(3124\to 2314\to 1234\),在 \(1\) 交换的那步 \(1\) 被少算了 \(2\) 的贡献,原因是 \(a_j\) 往前交换时 \((a_j,i)\) 中的数已经换到 \(i\) 之前,因此 \(a_j\) 实际被少算的贡献是 \(i-a_j\),即 \(f_{i,pos_i}\leftarrow f_{i+1,q}+\sum\limits_{j=pos_i+1}^{q-1}[a_j<i](i-a_j)\)。之后可以当作正常情况计算。
构造方案直接逆着 DP 的最优转移走回去,这个数的真实下标为前面比他小的数加上比他大且交换后位置在它前面的数。每次暴力求坐标即可,复杂度 \(O(n^2)\)。
**P11983 [JOIST 2025] 展览会 3 / Exhibition 3(区间最小点覆盖,上下界贪心,复杂度均摊技巧,倍增均摊技巧)
题意
有序列 \(\{a_n\}\),令 \(b_i=\max\limits_{i=l_i}^{r_i} a_i\),重排 \(a\) 最大化 \(b_{1\sim m}\) 的字典序。数据范围 \(10^5\)。
题解
考虑从大到小贪心。
对每个不同的 \(a_i\) 跑动态《detect》找最大前缀使得最小点覆盖 \(C<=cnt_{a_i}\)。
所选区间必定是一个前缀加一些东西,只保留这个前缀必定 \(C=cnt_{a_i}\)。
考虑先找到这样的前缀,如果二分,每次只删一个必定爆,考虑均摊,使用倍增 trick,找到最大的 \(2^k\),然后在 \([2^k,2^{k+1})\) 二分。这样二分区间长度必定不超过删除的点个数,复杂度均摊正确。
接下来考虑怎么加入零散区间,区间最小点覆盖有一个 trick 是上下界贪心,具体地考虑正反做两遍贪心,这样正贪心跑出来的是字典序最小解,反贪心跑出来的是字典序最大解,根据直觉,解是连续的,因此记两遍贪心第 \(i\) 个点的位置为 \([tl,tr]\),则在其他点保持自由的前提下,随意指定 \(i\) 在 \([tl_i,tr_i]\) 的某个位置,必定存在合法的解。
证明:必定可以选出【贪心答案】个不相交区间,因此 \([tl,tr]\) 互不相交,记 A(x) 表示覆盖 R<x 的最小点数,B(x) 表示覆盖 L>x 的最小点数,记 \(p_i\) 表示第 \(i\) 个点的位置,存在 \(p_i=x\) 的解当且仅当 \(A(x)>=i-1,B(x)>=ans-i\),由不交性质,任取 p_i\in [tl,tr] 均可保证这一点。
因此如果加入区间与某个 \([tl,tr]\) 有交,则可以加入,考虑区间加入后 \([tl,tr]\) 如何变化,如果存在 \([tl,tr]\) 被这个区间包含,则无需做任何改变,否则可以加入。
加入时,唯一问题是更新 \([tl,tr]\),更新 \(tr\) 为例,每次相当于重新跑一遍贪心,按 \(r\) 顺序遍历所有区间。找第一个 \(>r\) 的 \(tr_p\),当 \([l,r]\) 不能被 \([tl_{p-1},tr_{p-1}]\) 覆盖时,将 \(tr_p\) 改为 \(r\)。
\(tr_p\) 的修改会导致连锁反应,往后继续贪心修改,当无法进行修改时(\(tr_p=r\) 已经成立)退出。
复杂度看起来是平方的,但是它跑的飞快,测试点最大耗时 450ms。
(todo)复杂度证明或证伪。
*CF1540C2 Converging Array (Hard Version) *2900(相邻元素操作,找被操作的极长前缀,根据性质缩小范围,保序回归模型)
题意
有一个过程作用于长度为 \(n\) 的数组 \(a\) 和长度为 \(n-1\) 的数组 \(b\)。
进行如下操作 \(+\infin\) 次:
- 随机选择一个整数 \(i\)(\(1 \le i \le n-1\)),将 \(a_i\) 赋值为 \(\min\left(a_i, \frac{a_i+a_{i+1}-b_i}{2}\right)\),并将 \(a_{i+1}\) 赋值为 \(\max\left(a_{i+1}, \frac{a_i+a_{i+1}+b_i}{2}\right)\),不进行任何取整。
可以证明,数组 \(a\) 会收敛,定义函数 \(F(a, b)\) 表示经过该过程后 \(a_1\) 收敛到的值。
给定数组 \(b\) 和数组 \(c\)。对于 \(q\) 个不同的 \(x\),统计有多少个第 \(i\) 项在 \([0,c_i]\) 之间的整数数组 \(a\) 满足 \(F(a, b) \geq x\)。答案对 \(10^9+7\) 取模。
题解
操作相当于将差值不超过 \(b_i\) 的相邻元素进行调整。
那么最后序列的相邻差值必定 \(\geq b_i\)。
考虑分析最后的序列,设其为 \(f\)。
对于限制和修改全部依赖相邻元素的操作,可以找出一个没有被操作的位置,则前后序列独立。
若 \(f_{i+1}-f_i>b_i\),则 \(i,i+1\) 没有进行操作,如果进行操作,最后一定变为 \(f_{i+1}-f_{i}=b_i\)。
因为要限制 \(f_1\),考虑找出第一个没有被操作的位置 \(p\)。
这样 \(f_{i}-f_{i-1}=b_{i-1}\quad (i\leq p)\),则有:
即 \(pf_1+\sum\limits_{i=1}^{p-1}(p-i)b_i=\sum\limits_{i=1}^{p} a_i\)。
记 \(sb_p=\sum\limits_{i=1}^{p-1}(p-i)b_i,sa_p=\sum\limits_{i=1}^{p}a_i\),\(f_1=\frac{sa_p-sb_p}{p}\)。
我们不知道那个位置是 \(p\),猜测取所有 \(p\) 的最小值即为 \(f_1\)。
证明:\(f_1\geq \min \frac{sa_p-sb_p}{p}\) 根据上述结论可得,\(f_1\leq \min \frac{sa_p-sb_p}{p}\) 的证明比较困难(不过赛时应该不用证)。
这是一个类似保序回归的操作。
令 \(x_i=a_i-\sum\limits_{j=1}^{i-1}b_j,S_i=\sum\limits_{j=1}^{i} x_j\),操作可变为若 \(x_i<x_{i-1}\),将 \(x_i,x_{i-1}\) 变为 \(\frac{x_i+x_{i-1}}{2}\)。
注意到 \(sa_p-sb_p=S_p\)。
观察到:
- 操作过程中每个位置的 \(S\) 单调不增。
- \(x\) 单调不降。
记最终序列为 \(y\)。
因此 \(\sum\limits_{i=1}^{k} y_1\leq \sum\limits_{i=1}^{k} y_i\leq \sum\limits_{i=1}^{k} x_i\),即 \(y_1\leq \frac{S_k}{k}\) 对所有 \(k\) 成立。
故 \(f_1\leq \min \frac{sa_p-sb_p}{p}\) 得证。
对着 \(sa\) 的限制 DP 可以做到 \(O(qn\sum c)\),限制形如 \(sa_i\geq ix+sb_i\),值域很小因此有用的 \(x\) 不多,考虑缩小范围,以下情况是平凡的:
- \(\exist i,ix+sb_i< 0\),即 \(x<\max \frac{-sb_i}{i}\)。
- \(\forall i,ix+sb_i>\sum\limits_{j=1}^{i} c_j\),即 \(x>\frac{sb_i+i\max c}{i}\),可视为 \(x>\frac{sb_i+i\max c}{i}\)。
因此有用的 \(x\) 只有 \(O(\max c)\) 个,复杂度 \(O(n\cdot \max c\cdot\sum c)\)。
QOJ 1197. Draw in Straight Lines(最小割建模,将特定点取反刻画“同时属于 S 有额外贡献”的约束)
题意
给定 \(n\times m\) 的网格,初始全为白色。
给定 \(A,B,C\),你可以进行以下两种操作:
- 选择一个 \(1\times x\) 的矩形,花费 \(Ax+B\) 将矩形中的元素染为黑色或白色。
- 选择一个位置 \((x,y)\),花费 \(C\) 将位置 \((x,y)\) 染为黑色或白色。
要求:
- 同一个位置不能被染色超过两次。
- 若一个位置被染为白色,则不能再被染为黑色。
给定目标状态,求从全白网格染为目标状态的最小化费。
\(1\leq n,m\leq 40\)。
题解
同一个位置不能被染色超过两次比较难以限制,考虑分析性质,容易(?)发现,在上述限制下,我们不会对一个格子同方向刷两次。
数据范围比较特殊,考虑网络流相关的做法。
记 \(a_{i,j},b_{i,j},c_{i,j},d_{i,j}\) 分别表示一个格子被横向刷黑、纵向刷黑、横向刷白、纵向刷白的操作次数,\(a,b,c,d\in \{0,1\}\)。
\(a+c\leq 1,b+d\leq 1\)。
对于黑格,要求 \(c=d=0\),当 \(a+b=0\) 时有额外 \(c\) 的贡献。
对于白格,要求 \(a+b\leq 1\),当 \(a=1\) 时 \(c=0\),当 \(b=1\) 时 \(d=0\),当 \(a+b=1\land c+d=0\) 时有额外 \(c\) 的贡献。
由于 \(a+c\leq 1\) 的限制不弱于图上最大独立集,因此做不了。
仿照二分图最大独立集,对一些变量取反,这里 \(x+y\leq 1\) 的限制对有 \((a,c),(b,d),(a,b)\),只保留这些限制,原图为二分图,\(b,c\) 构成一侧的点,考虑对 \(b,c\) 取反,然后就是最小割板子了。
还有一个问题是如何计算贡献,显然 \(A\) 的贡献就是 \(\sum a+b+c+d\),容易计算,\(B\) 的贡献在 \(a_{i,j}\neq a_{i+1,j}\) 时计算,\(bcd\) 类似,这也可以用最小割刻画,实现时可令边界 \(a_{0,y}=a_{x,0}=0\) 以方便建图,\(bcd\) 类似。
*260129A(点减边,欧拉定理,相邻限制刻画,推广特殊情况)
题意
有一个 \(n\times m\) 的网格图,网格中第 \(x\) 行第 \(y\) 列的格子记作 \((x,y)\)。
定义一种对该网格图的染色 \(C\) 为将每个格子染成黑或白的颜色之一。
对于一种染色方案 \(C\),我们构造一个有向图 \(G(C)\),它的点与 \(C\) 中的黑色格子一一对应,边集按照如下方式确定:
- \(\forall 1\le x\le n,1\le y<m\),若格子 \((x,y)\) 和格子 \((x,y+1)\) 都是黑色的,则从格子 \((x,y)\) 对应的点向格子 \((x,y+1)\) 对应的点连一条边权为 \(1\) 的有向边,从格子 \((x,y+1)\) 对应的点向格子 \((x,y)\) 对应的点连一条边权为 \(2\) 的有向边。
- \(\forall 1\le x<n,1\le y\le m\),若格子 \((x,y)\) 和格子 \((x+1,y)\) 都是黑色的,则从格子 \((x,y)\) 对应的点向格子 \((x+1,y)\) 对应的点连一条边权为 \(3\) 的有向边,从格子 \((x+1,y)\) 对应的点向格子 \((x,y)\) 对应的点连一条边权为 \(4\) 的有向边。
我们称一种颜色方案 \(C\) 是合法的,当且仅当对于 \(G(C)\) 中的任意两个点 \(x,y\),都存在从 \(x\) 到 \(y\) 和从 \(y\) 到 \(x\) 的最多经过两种边权的路径。
现在,我们给网格图中每个格子填入一个 \(1\sim nm\) 的数,保证所有格子中的数构成一个 \(1\sim nm\) 的排列。
定义染色方案 \(C_i\) 为将所有填入的数 \(\\le i\) 的格子染成黑色,其余格子染成白色。
有 \(q\) 次操作,每次操作形如:
- 给定 \((x_1,y_1),(x_2,y_2)\),交换这两个格子中的数。
- 给定 \(l,r\),查询 \(C_l,C_{l+1},...,C_r\) 中有多少个染色方案是合法的。
\(1\leq nm\leq 2\times 10^6\),\(1\leq q\leq 2\times 10^5\)。
题解
赛时对有解条件的刻画是:连通、行和列不存在形如 \(<i\ >i\ <i\) 的结构,这样我的操作变为了对 \(a_{i,j}\),找出 \(a_{1\sim i-1,j}\) 的最小值 \(x\),\(a_{i+1\sim n,j}\) 的最小值 \(y\),对 \([max(x,y),a_{i,j}) +1\)。
这样修改极其困难,考虑分析特殊情况,对于 \(n=1\) 相当于构成 \(<i\) 的数连续段(赛时也意识到了这一点)。
考虑推广特殊情况,不存在形如 \(<i\ >i\ <i\) 的结构相当于每行每列只有一个连续段。
由于需要处理修改,应该优先考虑用局部、相邻的限制刻画,将段数刻画为 \(\sum [col_{i,j}\neq col_{i,j-1}]\),定义一行合法当且仅当这一行 \(段数-[这一行有数]=0\)。那么要维护段数,只需要在 \(a_{i,j}<a_{i,j-1}\) 时将 \([a_{i,j-1},a_{i,j}] +1\) 即可。当一个行或列有数时需要额外贡献 \(-1\) 的贡献,因此每行维护可删堆查询最小值。
最后是连通性,赛时不会维护面数,根据欧拉定理只需判断 \(V-E+F-1=0\),还是在值域线段树上维护 \(V-E+F\),\(V,E\) 是好维护的,\(F\) 在上述限制下退化为 \(2\times 2\) 的方格,也是好维护的,只需要对每个方格区域,在这个方格 \(a\) 的 \(\max\) 到 \(nm\) 这个区间 \(+1\) 即可。
所有限制都是相邻限制,容易维护两点交换。
需要将交换视为两次修改并独立处理,否则可能出现一条边被删两次再加两次的情况,这样贡献变为 \(2(new-old)\),不正确。
需要实现的数据结构是区间加、区间最小值计数。
*【集训队论文】在线二维数点(归并树、定期重构)
题意
无点权在线二维数点,要求 \(O(n)\) 空间 \(O(n\log^2 n)\) 时间。
题解
直接树套树即可做到 \(O(n\log^2 n)\) 时间和 \(O(n)\) 空间。
引入新的数据结构:归并树。
原理是将归并排序的过程存储下来,从而在得知当前节点 \(\leq p\) 的数字个数时,\(O(1)\) 算出当前节点的左儿子 \(\leq p\) 的数字个数。
考虑用这个做二维偏序,即区间 \(\leq k\) 的数字个数怎么做。
建立线段树,每个节点存储 \(01\) 串,第 \(i\) 位为 \(1\) 当且仅当这个节点内第 \(i\) 小的数字位于右子树。
我们显然可以求全局 \(\leq p\) 的数字个数,那么我们只需模拟线段树查询,推算出 \(O(\log n)\) 个区间 \(\leq p\) 的数字个数即可。
推算的过程是查询 \(01\) 串 \(p\) 前缀 \(0\) 的个数,将 \(01\) 串压位然后预处理每 \(64\) 位的前缀和,相当于 \(B=64\) 分块,然后预处理块间前缀和。
这样查询是 \(O(\log n)\) 的,空间是 \(O(\frac{n\log n}{w})=O(n)\),修改需要重构整个 DS。
考虑定期重构,散操作用树套树实现,每 \(B\) 次重构,复杂度 \(O(\frac{n}{B}n\log n+B\log^2 n)\),空间 \(O(n+B\log n)\)。取 \(B=\frac{n}{\log n}\) 可以实现线性空间复杂度和 \(O(n\log^2 n)\) 的时间复杂度。
提交记录 被卡空了。
可以二进制分组,并将线段树内 vec 改为外层的 vec<vec> 来通过,但是懒得写了。
*260201B/[AGC066E] Sliding Puzzle On Tree 黑(等价类的刻画,复杂度均摊,分析性质)
题意
给定一棵有 \(N\) 个顶点的树,顶点编号为 \(1\) 到 \(N\)。树的第 \(i\) 条边连接顶点 \(u_i\) 和顶点 \(v_i\)。
对于 \(K=1,2,\ldots,N\),请解决以下问题:
有 \(K\) 个编号为 \(1,2,\ldots,K\) 的石子,第 \(i\) 个石子初始放在顶点 \(i\)。你可以重复进行如下操作:
- 选择一条连接顶点 \(u\) 和 \(v\) 的树边,且 \(u\) 上有石子而 \(v\) 上没有石子。将 \(u\) 上的石子移动到 \(v\) 上。
求所有可能的石子最终分布方案数,答案对 \(998244353\) 取模。注意,如果某个编号的石子所在顶点不同,则认为是不同的分布方案。
\(1\leq N\leq 2\times 10^5\)。
题解
容易发现,忽略石子编号的情况下,所有状态均可达。
引理 \(1\):若存在一个局面 \(S\) 使得两个石子 \(a,b\) 可以在不影响其他石子位置的情况下交换位置,则在任意可以由 \(S\) 到达的局面 \(T\) 下,都存在一个操作方案使得 \(a,b\) 位置互换且其他石子位置保持不变。
证明 \(1\):记 \(R(S)\) 表示 \(S\) 交换 \(a,b\) 后的局面。令在局面 \(S\) 交换 \(a,b\) 的操作序列为 \(Op\),由 \(T\) 变为 \(S\) 的操作序列为 \(X\),考虑在 \(T\) 上进行操作 \(X,Op,X^{-1}\),由于操作只依赖那个顶点有石子,不依赖石子的具体编号,因此对于操作而言,\(S,R(S)\) 本质相同。因此在 \(T\) 局面操作 \(X,Op\) 后变为 \(R(S)\),再操作 \(X^{-1}\) 后变为 \(R(T)\)。
称引理 \(1\) 中的石子 \(a,b\) 是可交换的。
引理 2:若 \(a,b\) 可交换、\(b,c\) 可交换,则 \(a,c\) 可交换。换言之,将可交换石子连边,图构成若干个团的并。
证明 2:先交换 \(a,b\),再交换 \(a,c\),最后交换 \(b,c\) 即可达到交换 \(a,c\) 的效果。
由上述两个引理,不难发现,将可交换石子连边,每个团内的石子可视作等价类,可以随意互换,不同等价类的石子之间不可互换。
记等价类的大小为 \(s_1,s_2,\dots\),则 \(k\) 固定时答案为 \(\binom{n}{k}\prod s_i!\)。
我们希望使用原图结构来刻画等价类的关系,手动模拟一下可以发现,度数为 \(2\) 的链比较特殊,其特殊之处在于中间一旦有石子,则会把两边的连通块堵死,两边连通块不能进行交换。
定义一个导出子图可以帮助 \(a,b\) 交换,当且仅当存在一种方案,满足:
- 石子 \(a,b\) 到达导出子图 \(A\)。
- \(A\) 至少存在一个位置不是石子。
- \(A\) 不存在长度 \(\geq H\) 的链,满足链上除头和尾以外点数均为 \(2\)。其中 \(H=n-k\)。
下面归纳的证明,若存在满足如下条件的导出子图 \(A\),且 \(a,b\) 满足上述的前两个条件,则 \(a,b\) 一定在一个等价类内。
显然一个点符合条件,因为不可能有两个不同的石子到达一个点。
若两个导出子图 \(A,B\) 符合条件,即内部石子可以互换,且中间的链长 \(<H\)。
我们可以任意安排空位的位置,将空位全部安排在链上,并且预留一个空位在 \(A\) 中,且这个空位与链距离为 \(1\),那么可以将 \(B\) 中一个与链距离为 \(1\) 的石子 \(x\),移动到 \(A\) 中预留的空位中。然后将 \(A\) 中一个与链距离为 \(1\) 的石子 \(y(y\neq x)\),移动到 \(B\) 原本 \(x\) 的位置中。
这样,\(x,y\) 完成了交换。若空位个数严格小于链长,则能到达 \(A\) 且能在 \(A\) 中预留一个空位的石子对都能交换。
反之,若存在链长 \(\geq n-k\),则该链必定被石子堵死,因此容易说明若不存在这样的导出子图,则 \(a,b\) 不在等价类内。
考虑在原图上维护导出子图以刻画等价类关系。
若两个导出子图不存在长度 \(\geq H\) 的链,则将两个导出子图合并,并将所对应的等价类合并。
因此两个导出子图 \(A,B\) 没有合并,当且仅当对于所有 \(a,b\),若 \(A,B\) 均不能帮助 \(a,b\) 交换,则 \(A\cup B\) 不能帮助 \(a,b\) 交换。
因此容易说明,合并后的导出子图对应的等价类无交集,即不存在两个导出子图对应的等价类相同。
一个想法是从大到小枚举 \(k\),用并查集维护导出子图,每次将链长 \(<n-k\) 的导出子图合并。、
答案和 \(s\) 有关,考虑对于一个导出子图 \(A\),如何求其对应的等价类大小。
正难则反,考虑求一定不在 \(A\) 等价类中的石子个数。
考虑 \(A\) 向外连接的若干导出子图,向外连接的链长必定 \(\geq H\)。
记 \(A\) 向外连接的若干连通块为 \(p_1,p_2,\dots\)。
则对于一个连通块 \(p_e\),一定不能到 \(A\) 的石子个数为 \(p_e-(H-1)\)。原因是这个连通块最多有 \(H-1\) 个空位(因为根据定义,有一个空位需要留在 \(A\) 以帮助石子交换),所以只能有链上的前 \(H-1\) 个石子进入 \(A\),由于我们可以任意安排空位的位置,因此这个界是可以取到的,并且链上石子顺序固定。
那么,\(A\) 对应的导出子图大小为:
因此维护 \(out\) 和 \(sz\) 即可,合并 \(A,B\) 时,记连接 \(A,B\) 的中间链长为 \(c\),\(out'=out_A+out_B-2\),\(-2\) 是因为指向中间链的两条边变为内部边,\(sz'=sz_A+sz_B+c-2\)。
由于每个连通块的贡献和 \(k\) 有关,因此无法动态维护,但是我们有性质 \(\sum c=O(n)\),即链长和是线性的,由于我们从大到小枚举 \(k\) 并合并了所有链长 \(<n-k\) 的链,因此每个链未被合并的时间总和不超过 \(O(n)\)。
由于导出子图个数与未被合并的链个数量级相同,因此每次暴力遍历所有未被合并的连通块,复杂度是正确的。
实现上搜出所有度数全为 \(2\) 的链,用 set 维护当前的所有导出子图。
*260202B(笛卡尔树刻画矩形覆盖,路径相关树上 DP,下标取 \(\max\) 卷积的线段树合并优化)
题意
MagicDark 在夜空向远处望去,有 \(n\) 扇窗户,\(m\) 颗星星,其中第 \(i\) 扇窗户在坐标 \((ax_i,ay_i)\),第 \(i\) 颗星星在坐标 \((bx_i,by_i)\),保证所有点坐标互不相同。
夜空中还有建筑物,一座建筑物形如一个矩形 \((x,0)\) 到 \((y,h)\),其中 \(x < y\),并且 \(x,y,h\) 都可以不是整数。
有星星的位置一定没有被建筑物覆盖,有亮着的窗户的位置一定被建筑物覆盖。建筑物对应的矩形可以有重叠。
MagicDark 想知道至少有多少座建筑物才能形成这样一幅夜景,\(n\) 扇窗户内的灯可以开关,关闭时无法被分辨。对 \(2^n\) 种窗户内灯的开关方案,推断出建筑物最少数目的和,答案对 \(10^9+7\) 取模。
\(1\leq n,m\leq 5\times 10^5\)。
题解
注意建筑物可重,因此直接贪心是错的,可能出现这种情况:
- 窗户 \((2,2),(4,2)\),星星 \((1,1),(3,3),(5,1)\)。此时答案为 \(1\)(\((x,y,h)=(2,4,2)\))。
考虑用笛卡尔树来刻画矩形覆盖,将星星坐标建立笛卡尔树,这样覆盖的矩形要么对应笛卡尔树的一个子树,要么在两个相邻星星之间无限往上延伸。将坐标离散化后,在横坐标没有星星的位置添加高度为 \(+\infin\) 的星星可以避免考虑后者。同时对于相同高度的星星只保留纵坐标最低的。
此时一个矩形对应一个笛卡尔树子树,记 \(R(i)\) 表示 \(i\) 子树对应的矩形,记 \(cov(i)=\{j|(ax_j,ay_j)\in R(i)\}\)。
考虑能覆盖一个窗户 \((ax,ay)\) 的矩形有哪些,经过上述处理后每个横坐标都对应一个星星,记坐标 \(x\) 的星星为 \(p_x\),可以发现,满足 \(p_{ax}\in cov(i)\) 的 \(i\),在笛卡尔树上构成以 \(p_{ax}\) 结尾的一条祖先方向的链。
具体地,这条链可以由如下方式得出(\(fa_w\) 表示 \(w\) 在笛卡尔树上的父亲):
- 令 \(w=p_{ax}\),每次将 \(w\) 加入集合 \(S\),然后令 \(w\leftarrow fa_w\),当 \(by_w\leq ay\) 时结束操作,此时 \(S\) 即为所求。
问题转化为:
给定一棵树和一个限制集合 \(X\),集合中的每条限制用 \((u,v)\) 描述,保证 \(u\) 是 \(v\) 的祖先,表示 \((u,v)\) 上必须选一个点。令 \(w(X)\) 表示满足集合 \(X\) 中所有限制,最小需要选择的点数,求 \(\sum\limits_{Y\subseteq X} w(Y)\)。
如果只要求求出 \(w(X)\),这是一个经典的贪心问题,将限制 \((u,v)\) 挂到 \(v\) 上,DFS 整棵树,维护约束集合 \(T\),当遇到 \(v\) 时在 \(T\) 中加入 \(dep_u\) 表示必须有一个深度 \(\geq dep_u\) 的节点。记当前节点为 \(x\),若 \(dep_x=\max T\),则在 \(x\) 处放置一个节点(答案加 \(1\))并清空 \(T\)。
可以发现我们只关心 \(\max T\),因此记 \(f_{u,i}\) 表示 \(u\) 子树,\(\max T=i\) 的答案和,\(g\) 表示对应的方案数,可以 DP 做到 \(O(n^3)\),进一步地,非平凡的转移形如 \(f_{u,i}f_{v,j}\to f'_{u,\max(i,j)}\),讨论 \(\max\) 的取法,可以前缀和优化做到 \(O(n^2)\)。
下标取 \(\max\) 的卷积可以使用线段树合并维护,具体地,\(f'_{u,k}=f_{u,k}f_{v,k}+f_{v,k}\sum_{i<k} f_{u,i}+f_{u,k}\sum_{i<k}f_{v,i}\),线段树合并时。假设当前合并区间 \([l,r]\),额外维护两颗线段树在 \([1,l-1]\) 的和 \(s1,s2\) 即可,每次向右递归时,令 \(s1\leftarrow s1+sum(t1,ls),s2\leftarrow s2+sum(t2,ls)\),其中 \(sum(t,u)\) 表示线段树 \(t\) 编号为 \(u\) 的节点内的和。递归到空节点时操作退化为区间乘法,递归到叶节点时使用上述公式算出合并后的 \(f'_{u,k}\) 即可。类似的题目有 NOI2020 命运。
由于不那么良心的空间限制,可能不允许你对 \(f,g\) 各开一颗线段树,考虑只维护 \(g\),转移时计算 \(f\) 的贡献,具体地,当我们在 \(x\) 放置节点时,对答案的贡献为 \(2^{n-sz_x}g_{x,[by_{fa_x},by_x)}\),\(sz_x\) 为 \(x\) 的笛卡尔树子树大小,注意只有 \(\max T\in [by_{fa_x},by_x)\) 时我们才会在 \(x\) 放置节点。
时空复杂度均为 \(O(n\log n)\)。
P6773 [NOI2020] 命运 黑(树上 DP,路径相关 DP,下标取 \(\max\) 卷积的线段树合并优化)
题意
给定一棵树 \(T = (V, E)\) 和点对集合 \(\mathcal Q \subseteq V \times V\) ,满足对于所有 \((u, v) \in \mathcal Q\),都有 \(u \neq v\),并且 \(u\) 是 \(v\) 在树 \(T\) 上的祖先。其中 \(V\) 和 \(E\) 分别代表树 \(T\) 的结点集和边集。求有多少个不同的函数 \(f\) : \(E \to \{0, 1\}\)(将每条边 \(e \in E\) 的 \(f(e)\) 值置为 \(0\) 或 \(1\)),满足对于任何 \((u, v) \in \mathcal Q\),都存在 \(u\) 到 \(v\) 路径上的一条边 \(e\) 使得 \(f(e) = 1\)。对 \(998,244,353\) 取模。
\(n \leq 5 \times 10^5\),\(m \leq 5 \times 10^5\)。
题解
称 \(f(e)=1\) 为我们选了边 \(e\),\(f(e)=0\) 为我们没有选边 \(e\),称一个限制 \((u,v)\) 被满足当且仅当我们选择了路劲 \((u,v)\) 上的至少一条边。
\((u,fa_u)\) 必须选择的充要条件是存在限制 \((x,y)\),\(y\in \text{subtree(u)},x=fa_u\),且 \((x,y)\) 在 \(u\) 子树内还没有被满足。否则 \((u,fa_u)\) 可以任意决定选或不选。
维护 \(y\in \text{subtree}(u)\) 且没有被满足的限制 \((x,y)\) 的所有 \(x\),自底向上状压 DP 可以做到 \(O(2^{n}\text{poly}(n))\)。
注意到只有 \(dep_x\) 最大的 \(x\) 有用,因此状态量可压缩为 \(O(n^2)\),令 \(f_{u,i}\) 表示子树 \(u\) 内,\(dep_x\) 最大值为 \(i\) 的方案数,没有满足条件的 \(x\) 则 \(i=0\),答案为 \(dp_{1,0}\)。同时每个 \(y\) 只用保留最深的 \(x\)。
转移时,先卷子树,子树卷积为 \(f_{u,i}f_{v,j}\to f'_{u,\max(i,j)}\),这是经典的线段树合并形式。
然后如果不选 \((u,fa_u)\),则 \(f\) 不变,否则 \(f_{u,i}\to f'_{u,0}\)。
必须有 \(i<dep_{fa_u}\) 才能不选 \((u,fa_u)\),特判 \(x=fa_u,y=u\) 的情况,然后进行转移:
- 对于 \(i>dep_{fa_u}\),\(f_{u,i}\leftarrow 0\)。
- 对于 \(i=dep_{fa_u}\),\(f_{u,i}\to f'_{u,0}\),然后 \(f_{u,i}\leftarrow 0\)。
- 对于 \(i<dep_{fa_u}\),\(f_{u,i}\to f'_{u,0}\)。
由于只进行后两个转移操作已经保证 DP 正确,因此无需显式进行第一个操作。时间复杂度 \(O(n\log n)\)。

浙公网安备 33010602011771号