3月杂题
省选后再学多项式相关技巧了!现在得复习一些更重要的算法。
0.我复习了/补了哪些算法
动态更新。
数学:多项式取模,常系数齐次线性递推,Min25筛,BSGS,ExLucas,斯特林反演,线性规划对偶。
ds:区间历史最值,吉老师线段树,线段树分裂,树哈希,LCT,kd-tree,最小割树。
字符串:PAM,广义SAM(在线)。
其他:决策单调性优化,slope-trick。
1.CF1768F Wonderful Jump
一眼决策单调性,但是二眼发现看错了。
考虑值域为 \(n\) 有什么用:如果从 \(i\) 跳到 \(j\) ,显然 \(min*(j-i)^2\le (j-i)n\) ,后者是一格一格跳的代价上界。
于是 \(min*(j-i)\le n\) 时我们才会从 \(i\) 跳到 \(j\) 。
看到平方,考虑 \(a^2+b^2\le (a+b)^2\) 。所以如果 \(i\) 到 \(j\) 中存在 \(k\) 满足 \(a_k\le a_i,a_k\le a_j\) ,则先跳 \(i,k\) ,再跳 \(k,j\) 一定更优。
这个题就很简单了:\(j-i\le B\) 就暴力枚举;\(j-i>B\) 时有两种情况:
第一种是 \(a_j\) 为 \([i,j]\) 的 min ,要求 \(a_j\le \frac{n}{B}\) ,直接暴力往前扫,扫到第一个 \(a_j\le a_i\) 就停止。这个是均摊 \(O(\frac{n}{B})\) 的。
第二种是 \(a_i\) 为 \([i,j]\) 的 min ,在算 \(f_j\) 时枚举所有 \(x\le \frac{n}{B}\) ,以 \(x\) 最后一次出现的位置转移。
总复杂度 \(O(nB+\frac{n^2}{B})\),\(B=\sqrt{n}\) 时取到 \(O(n\sqrt{n})\) 。
2.P4227 [清华集训2017] 我的生命已如风中残烛
考虑直接模拟,然后如果出现环就把 \(L\) 对环长取模。因为每次 \(L\) 至少减半,所以复杂度是 \(O(Smn\log L)\) ,其中 \(S\) 是单次找 nxt 的复杂度。
事实上,这里可以均摊 \(O(\log n)\) ,考虑我们的环一定形成了凸包,而每个点在两个边组成的夹角内部才会被枚举到。
所以对于每个环,每个点只会被扫一次。我们预处理每个点与其他点的极角,每次找 nxt 时二分出第一个点,再枚举出往后第一个长度满足条件的。
复杂度就是 \(O(mn\log L\log n)\) 。
3.Baekjoon 19361 City United
很神秘啊,怎么想到的。
考虑枚举一个点集 \(S\) ,我们可以把它的权值表示成 \(\frac{2^{F(S)}\bmod 4}{2}\) ,其中 \(F(S)\) 是点集 \(S\) 的连通块个数。
考虑 \(\sum 2^{F(S)}\) 的组合意义:把每个点染成 \(0,1,2\) 三种颜色,并且 \(1\) 和 \(2\) 间不能有边。
直接 dp 即可,复杂度 \(O(m3^n)\) 。
感觉就是,判是否连通是不方便的。但是连通块有优秀的性质,利用此题的模数来进行计算。
4.「CSAcademy Round #35」Counting Quests(pjudge noip round 5 T3)
神神神。类似一些连通块计数问题,我们来考察任意一个区间集合的性质:
令 \(S_i\) 是覆盖 \(i\) 的集合,则不存在 \(l_1<l_2<r_1<r_2\) 使 \(S_{l_1}=S_{r_1}\neq S_{l_2}=S_{r_2}\) 。那么这就是一个类似于括号序列的结构:要么包含,要么不交。
所以我们进行这样一个过程:初始 \(i=1\) ,对于 \(S_i\) ,找到 \(S_j=S_i\) 的最大的 \(j\) ,然后 \(i:=j+1\) 。
这样就把 \(n\) 个位置划分出来了。现在转换角度,如果已经划分出来了,则你选择的区间 \([l,r]\) 要满足:要么存在一个 \([i,j]\) 使 \(i<l,r<j\) ;要么 \(l\) 等于某个 \(i\) ,要么 \(r\) 等于某个 \(j\) 。并且最后要使得 \(S_{i_1},S_{i_2},...,S_{i_k}\) 互不相等。
可以得到此时的方案为 \(f_k\prod 2^{\frac{(j-i)(j-i-1)}{2}}\) ,其中 \(f_k\) 就是 \(n=k\) 时的答案。
令 \(h_{i,j}\) 是把 \(i\) 个数划成 \(j\) 段的所有方案系数和。则 \(2^{\frac{n(n+1)}{2}}=\sum h_{n,i}f_i\) ,移一下项就能把 \(f_i\) 算出来了。
算 \(h\) 是 \(O(n^3)\) 的。复杂度 \(O(n^3)\) 。
事实上,\(H(x)=\sum\limits_{i\geq 1} x^i2^{\frac{(i-1)(i-2)}{2}}\) ,则 \(h_{i,j}=[x^i]H(x)^j\) 。那么 \(2^{\frac{n(n+1)}{2}}=[x^i]\sum f_jH(x)^j\)
如果 \(F(x)=\sum\limits_{i\geq 1} f_ix^i\) ,\(G(x)=\sum\limits_{i\geq 1} x^i2^{\frac{i(i+1)}{2}}\) ,则 \(G(x)=F(H(x))\) 。
\(F(x)=G(H^{-1}(x))\) ,使用拓展拉反:\([x^n]G(H^{-1}(x))=\frac{1}{n}[x^{n-1}]G'(x)(\frac{H(x)}{x})^n\) 。
由此可以 \(O(n\log n)\) 计算。由于这个题模数不是 NTT 模数,所以使用 \(n^2\) 求 exp 和 ln 的方法跑得更快,pjudge 上 alpha 的 std 应该也是这个。
5.P7216 [JOISC2020] 美味しい美味しいハンバーグ
矩形问题,考虑取出 \(l\) 最大,\(r\) 最小,\(d\) 最大,\(u\) 最小的四个矩形,则四个点一定在靠内的四条线段上。
如果 \(k\le 3\) ,那其中一个点一定是这四段围成的矩形的一个角。我们直接 dfs 下去,复杂度 \(O(nk^4)\) 。
否则:我们考虑一个矩形。
若和三个以上的边相邻,则它一定包含了关键点;若和一个边相邻,则它限制了这个边的上下界。现在考虑和两个边相邻的矩形:
把题目的限制转化成:两个矩形,在某个边界上不交,则不能同时取。如果满足这个限制,就一定有合法方案。
每个这样的矩形选择两个边中的一个,看做一个变量,这样就能 2-SAT 了。建图类似于前/后缀和优化。
6.[春季测试 2023] 密码锁
题外话:vp 的时候 \(k=4\) 写了个 \(O(n^2log n)\) 的做法结果写挂了。改对了之后有 \(95\)。
首先有一个重要的观察是,最大数和最小数一定不能在一行。
于是 \(k\le 2\) 简单。
对于 \(k=3\) ,二分答案之后,能确定每个拨圈在第三行可能的取值集合。考虑哪些 \([i-mid,i]\) 含有所有拨圈,通过差分可以 \(O(n)\) 维护,总复杂度 \(O(k^2n\log n)\) 。
类似的,\(k=4\) 就是一个扫描线,复杂度 \(O(k^3n\log^2 n)\) 。场上蠢了,一直在想 \(O(n^2)\) 的做法,即能不能绕开二分答案。
7.「JOISC 2020 Day1」扫除
首先考虑:所有修改进行后再询问,怎么弄。
我们把所有 \(y:=n-y\) ,则两个修改变成:每次给定一个 \(x\) ,对于\(l\le x\le r\) 的线段 \([l,r]\) ,把它变成 \([l,x]\) 或 \([x,r]\) 。称改成 \([x,r]\) 为操作 \(1\) ,改成 \([l,x]\) 为操作 \(2\) 。
如果只有操作 \(1\),发现这些操作是 无序 的,对于初始的 \([l,r]\) ,查询 \(\le r\) 的 \(x\) 的最大值即可。
现在我们有两种操作,不同的操作之间会互相制约。考察一个先发生的变成操作 \(2\) (权值为 \(x\)),如何影响后发生的操作 \(1\) (权值为 \(y\))。
你发现,如果 \(x<y\) ,那么 \(y\) 操作能影响的线段 \([l,r]\) 一定满足 \(x<l\le y\le r\) 。
由此可求出一个操作的影响范围。就把两种操作拆开了。但现在,我们同种之间的操作似乎变得有序了,不好搞。
以操作 \(1\) 为例:
我们令 \(p_i\) 表示一个操作 \(x_i\) 影响范围是 \(p_i\le l\le x_i\le r\) 。
按 \(x_i\) 从小到大的顺序进行操作,它就是正确的。
原因:如果有两个操作 \(i,j\) 满足 \(x_i>x_j,t_i<t_j\) ,那我们担忧,是否有 \(l<p_i\) ,因为顺序交换使之最后能变成 \(x_i\) 。
分类讨论:如果 \(p_i\le x_j\) ,那由 \(p\) 的定义,\(p_i\le p_j\) ,所以 \(l\) 不会被 \(i\) 和 \(j\) 操作。
如果 \(p_i>x_j\) ,那即使 \(l\) 先被 \(j\) 操作变成 \(x_j\),它也无法被 \(i\) 操作。
由此,我们用线段树维护 \(f(l)\) 表示 \(l\) 经过当前的所有操作后会变成什么。那插入一个 \((p,x)\) 等同于将所有 \(p\le f(l)\le x\) 的 \(f(l)\) 改成 \(x\) 。
我们在插入所有 \(x\le r\) 的操作后询问 \(f(l)\) 即可。操作 \(2\) 就类似的做就好了。
现在中途有查询和插入,套一个线段树分治就转化成上述做法了。复杂度 \(O(n\log^2 n)\) 。
8.P5781 [IOI2019]矩形区域
看 cz_xuyixuan 写的。
考虑枚举两列 \(j1,j2\),把哪些行合法处理出来,设这个行的集合是 \(S\) ,显然 \(\sum |S|\) 是 \(O(nm)\) 级别。
然后枚举 \(S\) 中的一行,以及它在 \(j2\) 这里是左端点还是右端点。我们预处理出来它往左能延伸到哪里即可。于是总复杂度 \(O(nm)\) 。
9.P7418 [USACO21FEB] Counting Graphs P
题外话:自己做出来的,但显然模拟赛场上写不完(而且我 T1 写挂了)。感觉挺简单的。
先把二分图判掉。然后我们算出以 \(1\) 为源点的奇偶最短路,设点 \(u\) 的偶最短路,奇最短路分别为 \(a_u,b_u\) 。
则新的图只能在满足 \(|a_u-b_v|=|a_v-b_u|=1\) 的 \((u,v)\) 间连边。
可以转化成:把一个点拆成 \(u_0,u_1\) ,相当于在 \((a_u>b_v)?u_0:v_1\) 和 \((a_v>b_u)?v_0:v_1\) 连边,然后所有权值 \(>0\) 的点都要被连至少一次。
就可以 dp 了,同时考虑 \(a_u+b_u=h\) 相同的点,把这个新图画出来,做法就很清楚了,不想写了。
10.P9138 [THUPC 2023 初赛] 公平合作
题外话:打 THUPC 中途摆了一个小时烂,导致这个 F 没冲完。队友也没调出来 B ,所以没进决赛。
如果算出 \(g_i\) 表示,先手把桶最终把桶填到只剩 \(i\) 单位的空间,先手赢的概率,\(f_i\) 表示先手当前桶还剩 \(i\) 单位空间,先手赢的概率。
那就有 \(f_i=\max(g_i,\sum f_{i-j}a_{j})\) 。
显然 \(i>2000\) 时我们只会取后者,所以暴力把 \(i\le 2000\) 的 \(f\) 求出来,再线性递推即可,即计算 \(\sum f_i[x^i](x^k\bmod A(x))\) 。
至于 \(g\) 是类似的, \(g_i=1-\sum\limits_{j=n-i}^{n-1}[x^j](x^{k+n-i}\bmod A(x))\) 。
注意我们单次卷积,取模可以 \(O(n^2)\) 实现。通过快速幂 \(O(n^2\log n)\) 算完 \((x^k\bmod A(x))\) ,直接每次 \(O(n)\) 乘上一个 \(x\) 并取模,就能算出来 \(x^{k+i}\) 。
11.LOJ 574 黄金矿工
重修模拟费用流!
费用流的模型是显然的: 连边 \((fa_i,i,+\infty,0)\) ,然后对于矿工,连边 \((S,u,A_u,1)\) ,对于黄金,连边 \((u,T,B_u,1)\) ,然后跑最大费用最大流。
现在我们要动态加边,但对答案有贡献的不一定是增广路,还有在残量网络出现的正环。因为我不会费用流,没考虑这个正圈,就没有拿下 \(O(nq)\) 的分。
你发现这两者的维护方式是类似的:
考虑一个 \((fa_i,i)\) 的边,它反向边的流量就是 \(i\) 子树内选择的黄金数量-矿工数量。
于是对于一个想加入的矿工 \(u\),我们找到它往上走第一个流量为 \(0\) 的反向边,设这个是 \((fa_v,v)\) ,发现如果选的另一个点不在 \(v\) 子树内,\((fa_v,v)\) 就是负的了。
于是在 \(v\) 子树内找到一个价值最大的未被选的黄金。这里我们把已选的矿工当成是未被选的黄金,权值为原来的相反数,就能实现消圈了。(后面的操作也能把已选黄金当未选矿工)
上面这个过程可以树剖实现,即维护一个线段树来计算反向边的流量,我们需要查区间内最右的 \(0\) 。还要维护一个线段树,需要查区间内的最强黄金并进行单点修改。
对于一个想加入的黄金 \(u\),同理地,如果另一个点如果能沿着反向边走到 \(u\) 的祖先,那这个点就能被选。
这里类似于 DDP 来维护:我们在每个点 \(u\) 维护一个 set \(C_u\) ,表示这个点上的矿工,以及每个轻儿子的子树内能走到 \(u\) 的最强矿工所构成的集合。
每次反向边流量改变,以及有矿工加入/删除时都会改变 \(C_u\) 。
我们想知道 \(top_u\) 子树内能走到 \(fa_{top_u}\) 的最强矿工。找到 \([dfn_{top_u},dfn_{down_u}]\) 内的最左的 \(0\) ,设之为 \(x\) ,然后查 \([dfn_{top_u},x)\) 的所有 \(C_i\) 构成的最强矿工即可。
此时改变了 \(C_{fa_{top_u}}\) ,递归地往上跳即可。
查询时同理,每次找到 \((dfn_u,dfn_{down_u}]\) 内最左的 \(0\) ,设之为 \(x\) ,然后查 \([dfn_{top_u},x)\) 内的所有 \(C_i\) 构成的最强矿工。再往上跳 \(u\) 。
对 \(C_i\) 的最大值再维护一个线段树即可。
想清楚就不难写,复杂度 \(O(n\log^2 n)\) 。
12.Xmas Contest 2020 D Determinant
这个矩形中有大量相同的数,于是对之做行查分,得到新的 \(b_{i,j}=a_{i,j}-a_{i+1,j}\) 。
发现对于 \(1\le j<i<n,b_{i,j}=0\) 。 于是求行列式时,如果排列中一个置换环大小 >1 ,那这个环一定包含 \(n\) ,且环的连边顺序是从小往大连,连到 \(n\) 后再连回去。
先把全是自环算了,然后令这个大环内的数是 \(p_1,p_2,...,p_m\) ,其中 \(m\geq 2,p_m=n\) ,且对于 \(i<m\) , \(p_i<p_{i+1}\)。则这个选法的贡献是 \((-1)^{m-1}C\prod_{i=1}^{m-1}b_{p_i,p_{i+1}} (1-C)^{n-m}=(1-C)^{n-1}C\prod_{i=1}^{m-1}\frac{1}{C-1}b_{p_i,p_{i+1}}\) 。
我们再来思考 \(b\) 有什么性质。根据定义不难得到,当\(i+1=j\) 时,\(b_{i,j}=C-1-C[i|j]\) ,否则 \(b_{i,j}=C[i+1|j]-C[i|j]\) 。
我们是可以把 \(b_{i,j}\) 的前后两个式子拆开算的。再算上 \(\frac{1}{C-1}\) 的系数,可以把问题转化成:
在 \(i,i+1\) 间有权值为 \(1\) 的边,\(i,k(i+1)(k>1)\) 间有权值为 \(\frac{C}{C-1}\) 的边,\(i,ki(k>1)\) 间有权值为 \(\frac{-C}{C-1}\) 的边。从 \(1\le i<n\) 的一个点出发,最后要走到 \(n\) ,问所有方案的权值乘积之和。
但是从 \(i\) 到 \(k(i+1)\) ,可以直接走,权值为 \(\frac{C}{C-1}\) ;也可以先走到 \(i+1\) ,再走到 \(k(i+1)\) ,权值为 \(-\frac{C}{C-1}\) 。于是这两种就抵消了,非常神秘。
于是我们就只会先走一段 \(i,ki\) ,再走一段 \(i,i+1\) 。
令 \(V=\frac{-C}{C-1}\) ,\(F(x)=V\sum\limits_{i\geq 2} x^i\) ,\(G(x)=\sum\limits_{i\geq 0} F(x)^i\) 。
则上述问题答案为 \(\sum [x^i]G(x)\left\lfloor\dfrac{n}{i}\right\rfloor-1\) 。如果能筛出来 \(G\) 的前缀和就好了。
虽然 \(G\) 不是积性函数,但由于 \(F*G=e\) ,且 \(F\) 的前缀和易求,我们仍然可以用杜教筛解决问题。复杂度 \(O(n^{2/3})\) 。
13.ARC145F Modulo Sum of Increasing Sequences
显然可以转化为单调递增序列。然后以生成函数列出答案: \(ans_k=[x^ny^k]\prod\limits_{i=0}^m (1+xy^i)\) ,其中第二维是以 \(p\) 为模数的循环卷积。
这个积式的最后 \(O(p)\) 项拎出来,使前面都是整块,形成一个 \(\prod\limits_{i=0}^{p-1}(1+xy^i)^m\) 的形势,最后再 \(O(p^3)\) 背包。
不难想到对第二维进行 DFT,我们想计算一个多项式 \(F_i(x)=\prod\limits_{j=0}^{p-1}(1+xw_p^{ij})^m\) ,我们只需保留后 \(p\) 项,最后再 IDFT 回去,有 \(G_i(x)=\frac{1}{p}\sum F_j(x)w_p^{-ij}\) 。
但是 \(p\) 不一定是 \(2^k\) 的形式,没法直接代进去算,我们需要进一步简化。
发现 \(F_i(x)\) 只与 \(g=\gcd(i,p)\) 相关。\(F_i(x)=\prod\limits_{j=0}^{\frac{p}{g}-1}(1+xw_{\frac{p}{g}}^{j})^{mg}=(1-(-x)^{\frac{p}{g}})^{mg}\) 。于是就完成了 \(F\) 的化简。
我们令 \(H_g(x)=(1-(-x)^{\frac{p}{g}})^{mg}\) 。现在考虑 \(G_i(x)=\frac{1}{p}\sum H_j(x)\sum [\gcd(p,k)=j]w_p^{-ik}\) 。
看到 gcd ,施加莫比乌斯反演,则 \(G_i(x)=\frac{1}{p}\sum\limits_{j|p} H_j(x)\sum\limits_{k=0}^{\frac{p}{j}-1} [gcd(\frac{p}{j},k)=1]w_p^{-ijk}=\frac{1}{p}\sum\limits_{j|p} H_j(x)\sum\limits_{d|\frac{p}{j}}\mu(d)\sum\limits_{k=0}^{\frac{p}{jd}-1}w_p^{-ijkd}\) 。
逆用单位根反演,得到 \(G_i(x)=\frac{1}{p}\sum\limits_{j|p} H_j(x)\sum\limits_{d|\frac{p}{j}}\mu(d)\frac{p}{jd}[\frac{p}{jd}|i]=\frac{1}{p}\sum\limits_{j|p} H_j(x)\sum\limits_{d|\frac{p}{j}}\mu(d)\frac{p}{jd}[p|ijd]\) 。
由此终于把单位根干没了,我们直接计算即可。复杂度是 \(O(m+n+pd(p)^3+p^3)\) 。
14.ABC278Ex make 1
设 \(g(i)\) 是 \(i\) 个互不相同的数能异或出 \(1\) 的方案,则答案为 \(g(n)-g(n-1)(2^m-n+1)\) 。
互不相同不太方便,考虑斯特林反演:
设 \(f(i)\) 是任意 \(i\) 个数异或出 \(1\) 的方案,则 \(f(n)=\sum\limits_{i=0}^n g(i){n \brace i}\) 。
由斯特林反演,\(g(n)=\sum\limits_{i=0}^n f(i)(-1)^{n-i}{n \brack i}\) 。(复习第一类斯特林·行:计算 \(x^{\overline n}\) 。)
转化成计算 \(f\) ,这就是 CF1603F,不详写了。(我只会那个联系 \(G(2x)\) 和 \(G(x)\) 的推法。考完省选再学 q-analog)
15.P6631 [ZJOI2020] 序列
考虑写成线性规划的形式。我们令一个集合 \(S\) 是一次操作可以 -1 的数的集合。
我们要求 \(\min \sum x_S\) ,\(\sum\limits_{i\in S} x_S\geq c_i\) ,\(-\sum\limits_{i\in S} x_S\geq -c_i\) ,\(x_S\geq 0\) 。
转成对偶就是 \(\max \sum (a_i-b_i)c_i\) ,\(\sum\limits_{i\in s}(a_i-b_i)\le 1\) ,\(a_i\geq 0,b_i\geq 0\) 。
显然可以把 \(a_i-b_i\) 替换成 \(d_i\) ,并且可以发现 \(d_i\in {-1,0,1}\) 。如果 \(d_i\le -2\) ,我们把它 +1 一定仍然合法;如果 \(d_i\geq 2\) ,那就 G 了。
由此 dp 即可。复杂度是线性的。
16.LOJ3637「2021 集训队互测」数列重排
题外话:今天场了两个互测,开心。
考虑算 \(F(k)\) 时,我们先思考只有 \(<k\) 的数怎么做。一个 mex 值 \(\geq k\) 的区间长度至少为 \(k\) 。
由于出现次数之差 <=1 ,我们可以构造出来一个序列,使每个长度为 \(k\) 的子段的 mex \(=k\) 。就比如说 \(0,1,2,3\) 出现次数分别为 \(X,X+1,X,X+1\) ,我们就 \(1,3,0,2,1,3,0,2,...\) 这样放。
现在有一些 \(\geq k\) 的数,于是问题转化成:一个 01 序列有 \(a\) 个 \(1\) ,\(b\) 个 \(0\) ,要使得 \(1\) 个数 \(\geq z\) 的子段尽量多。
我们令 \(x_i\) 表示第 \(i\) 个 \(1\) 后放了几个 \(0\) ,则 \(\sum\limits_{i=0}^a x_i=b\) ,我们要使得 \(\sum\limits_{i=0}^a \sum\limits_{j=i+z}^a (x_i+1)(x_j+1)\) 最大。
观察到,一对 \(x_i>0,x_j>0\) 一定有 \(j-i\geq z\) 。则我们 \(x_i>0\) 的位置,就是 \(zi\) 满足 \(z(i+1)\le a\) ,以及 \(a\) 。
此时在一个位置 \(i\) +1 ,发现它对答案的贡献是,当前的 \(\sum x_j+(a+1)\) 减去 \(2z-1-(z-1)[i=0 或 i=a]\) 再减去 \(x_i\) 。
那 \((a+1)+\sum x_j-(2z-1)\) 对答案的贡献是固定的;我们考虑 \(-x_i+(z-1)[i=0 或 i=a]\) 这个东西。
此时为了让答案最大,一定是先依次加 \(x_0\) 和 \(x_a\) ,让这两个位置都变成 \(z-1\) ;然后这两个位置的特殊性就消失了,我们轮流对每个合法的 \(x_i\) +1 即可。复杂度 \(O(n)\) 。
17.LOJ3643 「2021 集训队互测」球球
纯暴力就过了,离谱,还是第二优解&最短解。感觉这就是个讨论题阿,不是很难阿.jpg
还是借鉴了很多 zjk 博客。
我们思考,一开始在本体在 \(a\) 分身在 \(b\),经过 \(t\) 秒有一个要到 \(x\) ,可以怎么走。
第一大类:不开新的分身,有两种情况:
-
\(b=x\) ,转移到 \(([a-t,a+t],x)\) 。
-
\(|a-x|\le t\) ,转移到 \((a,b)\) 。
第二大类:开新的分身,此时 \(b\) 没用了。有两种情况:
- 在 \(x\) 放下分身, \(|a-x|\le t\) ,转移到 \(([x-(t-|a-x|),x+(t-|a-x|)],x)\) 。
2.在某地方 \(o\) 丢分身,再走到 \(x\) ,\(|a-o|+|o-x|\le t\),即: \(|a-x|\le t\) ,转移到 \((x,[\min(a,x)-\left\lfloor\dfrac{t-|a-x|}{2}\right\rfloor,\max(a,x)+\left\lfloor\dfrac{t-|a-x|}{2}\right\rfloor])\)
然后来思考一下转移,我们要维护两个集合 \(S,T\) 表示,可以是本体在 \(c\) ,分身是 \(S\) 中的一个数;可以是分身在 \(c\) ,本体在 \(T\) 中的一个数。然后要更新这两个集合。
先考虑一二类转移:
如果 \(S\) 中含有 \(x\) ,则 \(T'\) 加入 \([c-t,c+t]\) ;如果 \(|x-c|\le t\) ,那 \(S'\) 加入 \(S\) 的所有集合。
如果 \(c=x\) ,那 \(T'\) 中加入所有与某个 \(T\) 中数之差 \(\le t\) 的数。如果存在一个 \(T\) 中数与 \(x\) 之差 \(\le t\) ,则 \(S'\) 中加入 \(c\) 。
现在考虑三四类,与分身位置无关,我们令 \(H=T\) ,如果 \(S\) 非空就加入 \(c\) 。
考虑第三类,贪心地想让 \(|a-x|\) 最小,\(H\) 中找出这个数,把对应区间加进 \(T'\) 。
考虑第四类,首先有 \(x-t\le a\le x+t\) 。 \(x-t\le a\le x\) 时,\(a\) 更小区间更大;\(x-t\le a\le x+t\) 时,\(a\) 更大区间更大。
\(H\) 找出 \(\geq x-t\) 最大者,\(\le x+t\) 最小者,然后在 \(S'\) 中加入相应区间。
我们把 \(S,T\) 以 \([l_1,r_1],[l_2,r_2],...\) 的形式来维护。发现每次区间增加量是 \(O(1)\) 的,我们可以做到 \(O(n^2\log n)\),而这个是完全跑不满的,就 AC 了。
正解是,我们的操作相当于要维护一个集合,支持:加入一个区间的所有数,查 lower_bound,把集合变成所有 \(x\in S\) 的 \([x-t,x+t]\) 的并集。
我们用一个 set 来维护这个集合构成的若干区间。特别地,为了方便进行操作 3 ,我们不用要求这些区间两两不交,只用让 \(l,r\) 都是单调递增的即可,发现这样也是方便查 lower_bound 的。复杂度 \(O(n\log n)\) 。
如果要求两两不交,我们还需维护一个堆表示两个相邻区间的距离,这样才能搞操作 3 。感觉就挺麻烦,不过我应该见过一个类似的题。
18.CF1534G A New Beginning
复习 slope-trick。
这个题首先能观察到,确定了路径后我们每个点会去找路径上 \(x+y\) 相同的。不难想到搞一个 \((x,y)->(x+y,x)\) 的操作,则走法相当于往右/往右上走一步。
按照横坐标从左往右 dp,我们需要进行两个操作:一个是把 \(dp_i\) 变成 \(\min\limits_{j-i\le x} dp_j\) ,一个是 \(dp_i+=|x-i|\) 。
发现这个东西是个下凸壳,我们用 ds 来维护斜率的拐点。把最低点左右的拐点分开维护,则操作 \(1\) 相当于把右半部分拐点 +=x,打个 tag 维护;操作 2 需要看 \(x\) 和最低点的大小关系,分类讨论即可。
发现可以用堆维护,这个题就做完了。
19.P3642 [APIO2016] 烟火表演
复习 slope-trick。从下往上 dp ,相当于对拐点进行合并,可用左偏树维护。
还有对一段斜率为 -1,一段斜率为 1 的凸包求闵和,就是一直弹堆顶,弹到最后一个点代表斜率是 \(1\) ,平移最后两个拐点即可。
20.LOJ3693 「JOISC 2022 Day3」蚂蚁与方糖
求这个最大匹配,考虑拓展霍尔定理,求 \(|N(S)|-|S|\) 的最小值。
考察我们会怎么取 \(S\) ,如果存在两个数 \(i,j\) 满足 \(|i-j|\le 2L\) ,那 \(i\le k\le j\) 的所有数我们都会取。
其次,考虑计算 \(N(S)\) ,从左往右考虑的 \(S\) 的数,会加入一个区间的数,再减掉和上一个区间的交。
用线段树来实现取 S 的过程,\(val(p,0/1,0/1)\) 表示左右端点是否取了,即可往上算。
21.P8861 线段
口胡。
考虑一个 \(l\le 10^5\le r\) 的部分分,显然能把 \(l,r\) 拆开,然后变成 全局取 min ,插入,查 \(\sum \min(a,x)\) 的问题,可以 BIT+堆 维护。
拓展开来,考虑类似于猫树,把一个线段插到分治结构内第一个 \(x\le mid\le y\) 处,然后修改后如果不再跨越 mid ,就往下放。
修改相当于,如果 \(x\le mid\le y\) ,就是两个全局取 min ,否则,以 \(y<mid\) 为例,要把所有 \(l\le y\) 的找出来,修改往下放。查询也是类似的讨论。
这个过程可以 set+BIT+链表+并查集 实现。感觉很难写,开个坑有时间写。
22.P4003 无限之环
需要把所有接口封住,所以考虑把方格黑白染色。每个点能通过旋转来选择一些边界,然后我们要使得选择的边界可以全部贴上。
考虑对每个方格在四个方向上分别建点,然后能贴上的点之间连边。对于染色后的黑点,尝试通过四个点间的连边,让源点的流量流到一个子集;白点类似,连到汇点。
那分四种考虑:
不能转的就直接连;只连向一个点的,考虑源点先向初始点连费用为 \(1\) 的边(简称连 \(0\)),再从这个点出发,向相邻两个连 \(1\) ,向相对的连 \(2\) 。
连向三个点的,类似的,分别考虑初始三个点,先从源点连 \(0\) ,如果剩下那个点是对点,就连 \(2\) ,否则连 \(1\) 。
连向两个点的,考虑相对的一对点,源向初始点连 \(0\) ,初始点再向对点连 \(1\) ,发现这样恰好是正确的。
跑费用流即可。
23.[ARC155F] Directable as Desired
首先考虑钦定一个根,使得树的形态更清晰。
于是我们枚举一个点集 \(S\),使得 \(S\) 内的点和父亲间的边是 x->fa。
先考虑连 x->fa 的边的方案数,再考虑此基础上连 fa->x 的方案数。
第一部分的方案只和 \(|S|\) 大小相关,所以我们考虑 \(n\) 个点,连了 \(|S|\) 条 x->fa 边的森林一共有多少个,再除以 \(\tbinom{n}{|S|}\) 。
考虑构造超级点 \(0\) ,使森林内每棵树的根连向 \(0\) ,则变成 \(n+1\) 个点,\(0\) 的度数为 \(n-|S|\) 的方案数。
使用 prufer 序列处理这个问题,易得 \(\tbinom{n-1}{n-|S|-1}n^{|S|}\) ,除掉 \(\tbinom{n}{|S|}\) 得到 \(n^{|S|-1}*(n-|S|)\) 。
第二部分,考虑依次连每一条边,你发现边是无序的,影响了计数。所以我们给边打上标号,一开始连 x->fa 的时候要乘上 \(\prod\limits_{i\in S} d_i\) 。
然后这剩下 \(n-|S|-1\) 条边,它们的方案数与起点无关,并且每连一条边,终点的个数就会 -1 。所以这里方案就是 \((n-|S|-1)!\) 。
所以一个集合 \(|S|\) 的答案就是 \(\frac{1}{n\prod d_i!}\prod\limits_{i\in S} d_i\ (n-|S|-1)!(n-|S|)n^{|S|-1}=\frac{1}{n\prod d_i!}\prod\limits_{i\in S} d_i\ (n-|S|)!n^{|S|-1}\) 。
发现除了 \(\prod\limits_{i\in S}d_i\) ,其他项只与 \(|S|\) 有关,于是利用分治 NTT 求出 \(\prod (1+d_ix)\) 即可方便计算答案。
24.[ARC136F] Flip Cells
PGF 练习题,做过开关那个题基本也会做这个吧。
考虑设出 PGF 计算答案。令 \(F(x)\) 是经过 \(i\) 步第一次达到某个合法状态的概率的 PGF ,\(G(x)\) 是从合法状态到合法状态的 PGF,\(H(x)\) 是经过 \(i\) 步达到某个合法状态的概率的 PGF 。
则 \(F(x)G(x)=H(x)\) ,我们的期望是 \(F'(1)\) 。有 \(F'(1)=\frac{H'(1)G(1)-H(1)G'(1)}{G^2(1)}\) 。
现在需要求 \(G\) 和 \(H\) 。这两个问题是类似的,我们以求 \(H\) 为例。
我们令 \(f_i\) 表示,从初始状态开始翻转 \(i\) 个格子到达的合法状态的方案数。这是可以背包算出来的。
令 \(a=e^{\frac{x}{n}}\) ,则强转 EGF 可以得到 \(\frac{1}{2^n}\sum f_i(a-a^{-1})^{i}(a+a^{-1})^{n-i}\) 。
显然可以转化成一个 \(\sum c_ia^{2i-n}\) 的形式,这里 \(c_j=\sum [x^j]f_i(x-1)^i(x+1)^{n-i}\) 。我们从小到大枚举 \(i\) ,用类似背包的方式维护 \((x-1)^i(x+1){n-i}\) ,即可计算 \(c_i\) 。
而 \(\sum c_ia^{2i-n}=\sum c_ie^{\frac{2i-n}{n}x}\) 。则转回 OGF 可以得到 \(\sum \frac{c_i}{1-\frac{2i-n}{n}x}\) 。
但这个式子是有问题的,因为式子中存在 \(\frac{1}{1-x}\) 这样的项,代入 \(x=1\) 就 G 了。
考虑 \(F(x)=\frac{H(x)(1-x)}{G(x)(1-x)}\) ,这样上面的式子就可算了。复杂度 \(O(n^2m^2)\) 。
25.P7294 [USACO21JAN] Minimum Cost Paths P
今天场了个黑题,开心。
首先考虑只有两列怎么搞,你要找第 \(x\) 行横着走,则代价是 \((j-i)x^2+c_i+(s-x)c_j\)。
则这个二次函数在 \(x=\frac{c_j-c_i}{2(j-i)}\) 处有最值。看到这个,不难想到,取的列只会在下凸包上。这个证明是简单的。
把询问离线下来,然后每次在凸包上二分一下就好了,复杂度 \(O(n+q\log n)\) 。
26.CF1801E Gasoline prices
题外话:从跌倒的地方爬起来。这场打太烂了,现在状态正常后回顾这场的题,真的不难,很好上分阿/kk
先考虑树是链的时候怎么做,类似于 [SCOI2016]萌萌哒 ,倍增连边来维护最小生成树。
然后这个题,一开始想的是树剖,后来发现可以直接在树上做倍增,拆成三段直的路径相连,就和链的版本是类似的了。复杂度 \(O(n\log n)\) 。
27.CF1801F Another n-dimensional chocolate bar
显然可以 dp ,记 \(f[i][j]\) 表示考虑完前 \(i\) 个数后,剩下的数的乘积需要 \(\geq j\) 。
你发现 \(j\) 一定是某个 \(\left\lceil\dfrac{k}{i}\right\rceil\) ,这只有 \(O(\sqrt{k})\) 种。
转移是 \(\frac{1}{a}f[i][j]\left\lfloor\dfrac{a}{k}\right\rfloor\) to \(f[i+1][\left\lceil\dfrac{j}{k}\right\rceil]\) 。
类似于无记忆化的杜教筛的转移。复杂度 \(O(nk^{\frac{3}{4}})\) 。
28.[JOISC2023] festival2
咕咕咕。
29.[JOISC2023] passport
考虑有三种走法,一种是找到 \([l,r]\) 内 \(L\) 最小的,然后 \(l->L\) ;一种类似的往右走;一种是 \(l\le x\le r\) ,\(l->L_x,r->R_x\) 。
可以发现我们用前两种操作使区间扩大后,我们一定会在新增的范围内选 L/R 操作,否则一定会一直拓展到 [1,n] 。
所以这个题就分成两步,一步是找一个 \(l_u\le v\le r_u\) ,然后 \(u->v\) ,这样弄下去,可以线段树优化建图;一步是到了某个 \(u\) ,然后 \(l,r\) 分开拓展到 \([1,n]\) ,这可以线性预处理。
复杂度 \(O(n\log^2 n)\) 。
30.gym102331C Counting Cactus
考虑根据圆方树的形态进行 dp。令 \(f(S)\) 表示点集 S 内选边连成仙人掌的方案数。
随便取出 \(S\) 的一个固定的点 \(x\) 做根,然后分成两种情况:
-
\(x\) 和 >1 个圆点相连。令 \(g(S)\) 表示 \(x\) 只与一个圆点相连的方案数,则 \(f(S)=\sum g(T)f(S-T+\{x\})\) 。
-
\(x\) 和 =1 个圆点相连,相当于要求 \(g(S)\) ,再把 \(g(S)\) 加到 \(f(S)\) 上。
发现和圆点相连的这些点要构成一个环。于是我们考虑一个 dp:
\(h(i,j,S)\) 表示 \(S\) 划分成了若干子集,每个子集中都选了一个点串成一条链,链的左端是 \(i\) ,右端是 \(j\) 。
则 \(g(S)=\sum h(i,j,S-\{x\})\) ,其中 \(i\le j\) ,\(i,j\) 与 \(x\) 间有边相连。
这样转移就好了,复杂度是 \(O(3^nn^2)\) 的。
31.ABC272Ex Flipping Coins 2
考虑算每个点朝上的概率,再乘上 n。考虑算偶-奇,再算偶。此时可以表示成 \(\sum (-1)^{\sum [p_i\le b_i]}\) 的形式。
考虑枚举 S 使 \(p_i\le b_i\) 的恰为 S ,再枚举 \(T\) 与 \(s\) 不交,来进行容斥。
转换成枚举 \(K=S\cup T\) ,则他的系数是 \(\sum \tbinom{|K|}{i}(-1)^{i}(-1)^{|K|-i}=(-2)^{K}\) 。我们要计算 \(\sum (-2)^|K|f(K)\) ,其中 \(f(K)\) 表示 \(K\) 中的数都有 \(p_i\le b_i\) 的方案数。
把 \(b\) 从小到大排,则 \(f(K)\) 可以写成 \(\prod (b_{k_i}-i+1)\) 的形式。可以设计出来一个 dp ,转化一下可以写成 \(f_{i,j}=f{i-1,j-1}+f{i-1,j}(c_i+j)\) 的形式。
写成 GF,这个转移形如 \(G(x)=(x+c_i)F(x)+xF'(x)\) 。如果没有 \(xF(x)\) 就好了,怎么办呢。
看到有导数,尝试上点 \(e\) 。两边同乘 \(e^x\) 得 \(G(x)e^x=c_i(F(x)e^x)+x(F(x)e^x)'\) 。于是我们维护一个多项式,这个转移相当于把第 \(j\) 项乘上 \(j+c_i\) 。
则可以多点求值算出来这个多项式,再乘上 \(e^{-x}\) 就能得到原来的多项式。
复杂度 \(O(nlog^2n)\) 。
32.ARC150F Constant Sum Subsequence
考虑我们这个子序列肯定匹配的越后越好,设 \(f_s\) 表示所有长度为 \(s\) 的序列最远能匹配到哪里。有 \(nxt(f_i,j-i)->f_j\) ,其中 \(nxt(i,j)\) 表示 \(i\) 后第一个 \(=j\) 的位置。
这是一种类似于自己卷自己的结构,所以考虑分治处理。
分治之后考虑枚举 \(j-i=x\) ,观察哪些 \(i\) 是有用的。
\(f\) 是单调递增的,我们考虑 \(f_j\) 一定大于 \(f_{mid}\),所以 \(nxt(f_i,x)\) 要 \(>f_{mid}\) 才行。
而这等同于 \(f_i\geq pre(f_{mid},x)\) ,其中 \(pre(i,j)\) 是 \(i\) 或 \(i\) 前第一个 \(=j\) 的位置。由此可以二分出有用的 \(i\) 范围。
并且对于 \(f_i\geq pre(f_{mid},x)\) ,由于 \(f_i\le f_mid\) ,所以 \(nxt(f_i,x)=nxt(f_{mid},x)\) 。这是一个关于 \(x\) 的定值,转移相当于区间取 max ,线段树维护即可。
复杂度 \(O(nlog^2 n)\) 。
33.P9041 [PA2021] Fiolki 2
路径两两不交,想到用 LGV 引理计算答案。注意到行列式非零等同于矩阵满秩。
我们令 \(f_{u,i}\) 表示 \(i\) 到 \(u\) 的方案数,则 \([l,r]\) 的答案等同于,把 \(f_{u}\) 看成 \(k\) 维向量后 \([l,r]\) 的线性基大小。
考虑从小到大枚举 \(r\) ,维护当前的线性基,使编号尽量大,即可计算答案。
一个问题是不能直接计算 f ,可以取个模数,并且给每个边赋一个随机边权。
34.CF1767F Two Subtrees
好题啊。直接四维莫队是 \(O(n^{\frac{7}{4}})\) 的,过不去,所以我们要思考怎么利用子树的条件。
类似于 dsu on tree 来处理这个过程,则一个子树的信息可以表成一个长度为 \(O(n\log n)\) 的操作序列的前缀。
在这个操作序列上莫队就好了,复杂度 \(O(n\sqrt{n}\log n)\) 。
35.AGC039F Min Product Sum
我们令 \(a_i\) 是 \(i\) 这行的 min ,\(b_j\) 是 \(j\) 这列的 min ,我们按权值从小到达来填 a,b 并由此计数。
现在比较困难的是,想要取到一个 min ,就需要这一行/列至少有一个数 = min。所以我们容斥来做这个过程。
我们先填没被钦定的,再填被钦定的,这样就能顺便算出填矩阵的方案了。复杂度 \(O(n^4)\) 。
36. UOJ418 【集训队作业2018】三角形
复习 exchange argument。
考虑把操作顺序反过来,就是先操作父亲后才能操作它的儿子。操作一个点 \(x\) 相当于是石子总数先 += \(\sum w_v\) ,再 -= \(w_x\) 。一开始有 \(w_{root}\) 个石子,要使总数最大值最小。
可以把一个操作写成 \((s,m)\) 的形式,即总数变化量,过程中的最大值和初始值之差。有 \((a,b)+(c,d)=(a+b,\max\{b,a+d\})\) 。
先考虑只询问以 \(1\) 为根时的答案。考虑一开始有 \(n\) 个联通块,分别代表一个操作序列,每次选一个联通块,把这个联通块的序列接到它父亲的操作后面,合并两个联通块。
这样一定能构造出所有合法操作序列,所以我们以这个构造方式的来贪心:
考虑 \((a,b)\) 是否一定在 \((c,d)\) 前面。我们想发现这个二元组存在一种偏序关系。
由于这个二元组的加法有结合律,我们只需考虑 \((a,b)+(c,d)\) 是否比 \((c,d)+(a,b)\) 更好。
即判断 \(\max(b,a+d)<\max(d,b+c)\)。分类讨论一下,\(a,c\) 都 \(>0\) 时就是 \(a+d<b+c,a-b<c-d\) ;\(a,c<0\) 时就是 \(b<d\) ;\(a,c\) 正负性不同就是负的那个更优。
由此贪心即可,用一个 set,每次取出最小的联通块,和父亲连起来就好了。
对于每个子树,发现它的操作序列是整棵树操作序列的子序列,线段树合并维护即可。复杂度 \(O(n\log n)\) 。