2 月做题记录
P11651
考虑枚举二进制每一位 \(x\),求出有多少 \(i\leq j\) 使得 \(a_i +a_j\) 的第 \(x\) 位为 \(1\)。
枚举 \(i\),根据 \(i\) 这一位是 \(0/1\) 可以退出 \(j\) 的 \(x\) 后面这些位的一个范围限制。
对每一位按照只保留这位后面的数排序即可做到 \(O(n \log n \log V)\)。
但是 \(2\) 个 \(\log\) 过不了,注意到排序过程可以变为 \(O(\log V)\) 次归并两个序列的过程,查询可以离线下来双指针,于是可以做到 \(O(n \log V)\)。
P11653
我们要对基环树上的边定向或选择删除此边,使得加上那些有向边后图有欧拉回路的前提下保留的边尽量少。
在环上随便选一条边,分类讨论,这条边不选以及两种定向,弱连通图有欧拉回路等价于每个点入度等于出度,将环上边删去后 DFS 依次确定每条边方向。
P11656
我们发现 \(k\) 没有任何意义,因为撞到后就算停了下来那么由于那条线方向一样所以停不停都一样。
DP,\(f_i\) 表示只用 \([i,n]\) 的点,覆盖 \([i,n]\) 的最小数量。转移考虑覆盖 \(i\) 的位置是 \(i\) 向右或者是后面某个位置向左。可以发现转移只需要维护区间取 \(\min\) 区间求 \(\min\),线段树即可。
P11659
莫队,维护每个数出现次数,有多少 \(a_i : a_j = 2:3\),以及有多少 \(a_i:a_j=4:2\),瞎维护就行。
P11660
对于每个 \(b\) 单独考虑。
首先 \(a>b\) 时 \(a\) 与 \(a-b\) 答案一样,所以先将 \(a\) 对 \(b\) 取模
\(b\) 确定时,\(\lfloor \dfrac{x+a}{b} \rfloor=\lfloor \dfrac{y+a}{b}\rfloor\) 对 \(a\) 可以解出常数个范围。
对于每个 \(b\),将序列分块。显然询问区间和询问前缀互相规约,所以考虑前缀怎么做。每一块维护一个前缀和数组表示每个 \(a\) 的答案就行。
P11661
假设 \(n,V\) 同阶。
最值分治,变为区间询问有多少数 \(\bmod a = b\),离线根号分治,复杂度 \(O(n \sqrt {n \log n})\),很遗憾过不去,怎么改阈值也过不去。
注意到对 \(x\) 个区间做这个过程的复杂度为 \(x \sqrt n\),分治过程中若 \(x > \sqrt{V}\) 那还不如 \(O(n)\) 枚举。得到分治复杂度 \(T(n) = \max \limits_{k} (T_{k} + T_{n-k} + \min(n,k\sqrt V))\),出题人声称复杂度为 \(O(n\sqrt V)\)。
但是卡常卡空间,不好评价。
P11676
区间 DP,记 \(f_{i,j}\) 表示存在某 DFS 序使得 \([i,j]\) 是连续一段的最小答案,转移枚举 \(i\) 的子树转移点 \(k\),有 \(f_{i,j} \gets f_{i,k}+f_{k+1,j}+\max(0,a_{i,k+1})+v\),\(v\) 是撤销若干条边的答案,二维前缀和可以简单计算。
P11684
显然等价于查询前缀,那么只需要求 \(\sum \limits_{i=1}^n \sum \limits_{j=i+1}^m [j-i=\gcd(i,j)]\)。注意到 \(\gcd(i,j)=\gcd(j,j-i)\),所以 \(\gcd(i,j)=j-i\iff j-i\mid j\)。
枚举 \(x=j-i\),式子推一下可以整除分块,然后做完了。
P11685
直接线段树维护答案,但是三个位运算一起没结合律,所以只维护前缀有多少结果为 \(0/1\) 不能合并,但是可以维护若初始值为 \(0/1\),则前后缀有多少结果为 \(0/1\),这个东西就可以直接合并了。
CF1734E
如果没有 \(a_{i,i}=b_i\) 的限制,取 \(a_{i,j} = ij \bmod n\),容易验证正确性。
显然对于一个好矩阵,对一行都加上一个数仍然符合条件,于是做完了。
模拟赛 Div2 T1
能从 \(s\) 出发到达所有点的充要条件是,图中有且仅有 \(s\) 入度为 \(0\)。
考虑求出所有极小区间,也就是对于每个 \(l\) 求最小的 \(r\) 使得条件满足。
求出 \(r\) 很简单,求完后转数点即可。
模拟赛 Div2 T2
直接 DP 套 DP,记 \(f_{i,S}\) 即可做到 \(O(n2^V)\)。
注意到我们对于每个 \(S\) 只需要求最大的 \(i\),所以转记 \(f_{S}\) 表示最大的 \(i\) 使得 \(i\) 结尾结果可能为 \(S\)。
转移考虑要求 \(f_S\) 后面第一个相邻且都不在 \(S\) 内的两个数,直接维护可以做到 \(O(nV^2+2^VV^2)\) 时间与 \(O(nV^2+2^VV)\) 空间,时间常数很小能过,但空间会爆,结果你只需要分块存一些减小空间常数,然后卡卡常就能过。
事实上 jly 介绍了一个更优方法,我们不按照 \(S\) 从小到大转移,而是每次取 \(f_{S}\) 最小的 \(S\) 转移,这样空间不需要这么大的开销,时间复杂度还能做到 \(O(nV\log V+2^VV^2)\),有点牛。
模拟赛 Div2 T3
暴力做是贪心,每次将所有有石子的点往后移,每个点选择的是目前离终点最远的石子。
考虑每条边计算贡献,根据贪心,有进一步结论,只需要保留所有路径经过这条边的路径即可。
考虑树上问题,对于每条边将经过这条边的路径按到这条边距离排序,可以得到一个形如 \(\max \limits_{i=1}^k (d_i+k-i+1)\) 的式子,式子可以线段树合并。
环上问题可以简单讨论或拆成树上问题。
模拟赛 Div1 D1T3
结论:一个矩阵是好的当且仅当删掉空行空列后存在一个将矩阵划分为上下左右四部分的方法,使得左上全是 \(1\),右下全是 \(0\),左下和右上分别是好的。
证明:不会。
直接对这个 DP 可以做到 \(O(n^6)\)。
注意到 DP 状态只需要记子矩阵右下角为 \((n,m)\) 的,降到 \(O(n^4)\)。
转移过程,只要划分位置的行确定,列可以贪心选择,降到 \(O(n^3)\)。
LOJ6039
对于每种相同的 \(c\),必然取得是从大到小排序后的一段前缀。
记 \(f_{i,j}\) 表示考虑了 \(c \in [1,i]\) 的所有物品,总代价为 \(j\) 的最大答案。
转移按照 \(j \bmod i\) 分类,得到形如 \(f_{i,j}=\max \limits_{k} \{ f_{i-1,k}+g(j-k) \}\) 的式子。
注意到 \(g(x)\) 是上凸函数,所以 \(w_{k,j} = g(j-k)\) 是蒙日矩阵,\(f_{i,j}\) 有决策单调性,分治即可。
QOJ9737
首先显然能写出 DP,\(f_i\) 表示 \(1\) 到 \(i\) 的答案,转移枚举 \(j\),则 \(f_i=\max \limits_{j} \{f_j+w(j+1,i)\}\),其中 \(w(j+1,i)=c(s_i-s_j)\),且 \(c\) 容易二分计算。
如果 \(c\) 是凸的,则 \(w\) 满足四边形不等式,二分栈即可,不多赘述。
画出 \(c\) 的图像,发现其实是分段函数,每段是一条直线,这个图象甚至不是连续的,显然没有凸性。
把顶点连起来,图像连续且凸,但是 \(w(j+1,i)\) 需要下取整。
将下取整放在 \(\max\) 外面,二分栈即可。
GYM102586B
对于询问区间 \(l,r\),若起点 \(k\) 确定,显然有贪心策略,每次往两侧更近的走。
这个贪心式子可以写出来,假设 \(x\) 为最大的使得 \([k-x,k+x]\) 区间和不超过 \(s\) 的 \(x\),则可以发现答案可以简单维护前缀和计算。
询问区间 \(l,r\) 时,考虑区间中点 \(mid\),发现对于左侧的起点,不需要考虑右端点,右侧的则不需要考虑左端点。问题变为求 \(\max \limits_{i \in [mid,r]} val(i,r)\)。
不难验证 \(val\) 是蒙日矩阵,但是区间的限制不好办。
把询问区间拆成线段树上区间,离线对于线段树上每个点做分治即可。SMAWK 能做到更优复杂度但不必要。
ABC383G
记 \(s_i = \sum \limits_{j=i-k+1}^i a_j\),问题变为选 \(i\) 个位置,相邻两个位置差至少 \(k\),最大化选的和。
考虑分治,记 \(f_{l,r,a,b}(i)\) 表示在区间 \([l+a,r-b]\) 中选 \(i\) 个位置符合限制的最大的和。
不难证明 \(f\) 有凸性,合并时闵可夫斯基和即可。
注意到 \(r-l<k\) 时无需分治,于是总复杂度为 \(O(nk^2\log n)\)。
P10736
显然有 DP,\(f_{i,j}\) 表示前 \(i\) 块土地,第 \(i\) 块深度为 \(j\) 的最大价值。
转移形如 \(f_{i,j}=\max \{ f_{i-1,j},f_{i-1,j-1},f_{i-1,j+1}\} + p_i j\)。前面取 \(\max\) 转移有凸性,后面显然也有,维护差分,可以发现前面是插入两个 \(0\),后面是全局加,直接维护即可。
GYM104128H
对每条边算贡献。
DP,记 \(f_{i,j}\) 表示在 \(i\) 子树内选 \(j\) 个点的答案,合并子树是 \((\max,+)\) 卷积,计算父亲的贡献是 \(f_{i,j} \gets f_{i,j}+j(k-j)\)。不难验证凸性,所以合并子树是闵可夫斯基和,启发式合并或者平衡树有交合并均可。第二部分简单打标记即可。
GYM103202L
可以简单证明区间极差符合四边形不等式。
显然区间 \([l,r]\) 极差等于 \(\max \limits_{i,j \in [l,r]} \{a_i - a_j\}\),问题等价于选 \(k\) 个不交区间,最大化 \(\sum \limits_{i=1}^k |a_{l_i} - a_{r_i}|\)。
进一步等价于选 \(2k\) 个位置,每个位置选一个 \(1\) 或 \(-1\) 的权值,要求偶数相邻的位置不能相同,最大化权值乘以 \(a\) 的和。
DP,\(f_{l,r,-1/1/0,-1/1/0}(k)\) 表示区间 \([l,r]\) 选了 \(k\) 个区间,左侧是否还存在某个位置没有匹配,若有其权值是什么,右侧同理。分治并闵可夫斯基和即可。
QOJ9918
如果是单点加,对于每个点开动态开点线段树维护 DDP,查询时线段树二分即可。
路径加时,考虑离线后线段树合并,在两点 \(\operatorname{LCA}\) 处把这次修改删去就行。
CF1876G
暴力是从后往前贪心,正确性显然。
我们不容易刻画前缀加的形式,于是我们考虑贪心的过程:枚举 \(i\) 从 \(r\) 扫到 \(l\),若 \(a_i < x\),则答案加上 \(\lceil \dfrac{x-a_i}{2} \rceil\),然后 \(x \gets \lfloor \dfrac{x+a_i}{2}\rfloor\)。
如果不是 \(x \gets \lfloor \dfrac{x+a_i}{2}\rfloor\) 而是 \(x \gets \lfloor \dfrac{x}{2} \rfloor\) 那是非常容易的,显然只会操作 \(O(\log V)\) 次。我们希望类似地刻画这个东西。
离线进行扫描线,在 \(r\) 处加入 \(x\),在 \(l\) 处查询答案。容易发现如果两个 \(x\) 在过程中变得相同,那么之后答案的增量相同。
有一个看着就很对的做法,我们只维护本质不同的那些 \(x\),相同的 \(x\) 带权并查集维护,显然我们只需要维护连通块加与到根路径求和,这是很简单的。
复杂度怎么分析呢?考虑所有不同的 \(x_1,x_2,\cdots,x_k\),考虑势能函数 \(\sum \limits_{i=1}^{k-1} \log_2(x_{i+1}-x_i)\),可以分析复杂度为 \(O(n \log n \log V + n \alpha(n))\),有办法把 \(\log n\) 去掉,不过不是必要的。
CF1515H
按位与操作可以改为异或与或,所以只考虑异或与或。
建立 01-Trie,其实就是动态开点权值线段树。
操作显然可以将 \([l,r]\) 区间分裂后合并回去,这部分复杂度是一个 \(\log\) 的。
所以我们只需要维护全局操作。
全局异或是简单的,等价于某些位交换左右儿子。在根上打标记就行。显然标记可以直接复合。
全局或相当于有些位的所有点的左儿子会合并到右儿子上面。
我们考虑暴力一点。对于每次操作,如果某一位所有点都只有一侧有儿子,且是同一侧,那么这一位的或等价于异或。
对于每个点,记录子树内哪些位对应的点存在左或右儿子。
对点 \(u\) 子树或上 \(x\),如果 \(x\) 为 \(1\) 的那些位在子树内都只有某一侧有儿子且是同侧,问题变为这个子树异或某个数,打标记返回。否则递归两侧后做线段树合并。
分析一下复杂度,考虑势能分析。
记势能为每个点子树内有多少位同时存在左右儿子,显然初始势能为 \(O(n \log V)\)。每次往下递归都会使这个点势能至少减 \(1\),所以线段树合并次数为 \(O(n \log V)\),总复杂度 \(O(n \log^2 V)\)。
CF1523H
\(k=0\) 时怎么做?注意到有贪心策略,每次走到范围内 \(j +a_j\) 最大的点即可。倍增处理 \(f_{i,j}\) 即可。
\(k>0\),很自然地考虑 \(f_{i,j,k}\) 表示从 \(i\) 开始走了 \(2^j\) 步,至多删去 \(k\) 个点能到达的最大的 \(x + a_x\) 的 \(x\)。预处理复杂度 \(O(nk^2\log n)\)。
查询时,枚举 \(j\),尝试走 \(2^j\) 步,我们需要判断是否能走完后一步到 \(r\)。维护 \(h_k\) 表示至多删 \(k\) 个位置走到的 \(x+a_x\) 最大的 \(x\) 即可。复杂度 \(O((n+q)k^2\log n)\)。
CF2018E2
枚举每组大小 \(x\),尝试求出 \(f_x\) 表示至多分组数量。
也就是我们要选出若干段,使得段间不交,且每段内存在某个位置覆盖次数至少为 \(x\)。
贪心,按 \(r\) 小到大依次加入每一个和之前不交的区间,当最大覆盖次数为 \(x\) 时更新答案。
直接线段树维护可以做到单次 \(O(n \log n)\)。
注意到 \(f\) 单调不增且 \(f_x \leq \dfrac{n}{x}\),分治即可做到 \(O(n\sqrt n\log n)\),但无法通过。
考虑区间加全局 \(\max\) 能否优化。
由于区间加的右端点单调不降,我们只需维护后缀最大值。
维护所有后缀最大值和上一个位置的差分,显然差分的和加上最右边的位置的值即为答案。
后缀加时,找到 \(\geq l\) 的第一个后缀最大值并将其差分减 \(1\),和上一个后缀最大值相同时删去前面那个。
维护并查集和链表,即可做到单次 \(O(n \alpha(n))\),总复杂度 \(O(n\sqrt{n} \alpha(n))\),可以通过。
使用线性序列并查集能做到理论更优复杂度。
CF1707E
结论:\(f^k(l,r)=\bigcup \limits_{i=l}^{r-1} f^k(i,i+1)\)。
证明:
我们首先证明,若区间 \([l,r]\) 与 \([x,y]\) 有交,则 \(f(l,r)\) 与 \(f(x,y)\) 有交。显然交集中某个位置的 \(a\) 同时属于两个集合,所以有交。
对于原命题,\(k=0\) 显然成立。
\(k=1\) 时,区间左端点和右端点显然会在相邻两个中取到,并且后面也是区间,所以是对的。
\(k>1\),考虑归纳,我们只需证明区间左右端点相同,显然左右类似,以左端点为例。假设 \([L,R]=f^{k-1}(l,r)\),则 \(f^k(l,r)\) 的左端点为 \(\min \limits_{i=L}^R a_i\)。又因为 \([L,R]=\bigcup \limits_{i=l}^{r-1} f^{k-1}(i,i+1)\),所以 \(\min \limits_{i=L}^R a_i = \min \limits_{i=l}^{r-1} \min \limits_{x \in f^{k-1}(i,i+1)} a_x\),显然等于原式。右端点同理。因为 \(f^k(i,i+1)\) 相邻有交,所以相邻取并必然为区间。
证毕。
对于原题,考虑倍增,记 \(g_{i,j}\) 表示 \(f^{2^j}(i,i+1)\),按照 \(j\) 枚举后每层要维护 RMQ,复杂度 \(O(n \log^2 n)\) 或 \(O(n\log n)\)。
QOJ9559
动态开点线段树,第 \(0\) 棵树维护没被占用的行,操作相当于是线段树分裂与合并,问题在于怎么找某行的根。
我们肯定要对每个点维护父亲,问题变为求某行所在的点。
离线,将询问的点预先插入动态开点的线段树即可。
ARC192D
即要求 \(\dfrac{\operatorname{lcm}(S_i,S_{i+1})}{\gcd(S_i,S_{i+1})}=A_i\)。
对于每个质因数单独算贡献,显然把贡献和乘一起即为答案。要求互质,用总的减去不互质就行。
考虑质因数 \(p\),则要求即为 \(|b_i-b_{i+1}|=a_i\),\(b_i\) 为 \(S_i\) 中 \(p\) 质因数次数。直接做 DP 可以得到一个 \(O(nV^2)\) 左右的东西,但注意到 \(a_i \neq 0\) 的 \(a\) 总共只有 \(O(n\log V)\),所以直接跳过 \(a_i=0\) 的即可做到 \(O(Vn\log V+n\sqrt V)\),可以通过。
模拟赛 T1
确定叶向生成树后,显然有一个 DP 做法。
考虑状压 DP,记 \(f_{i,S}\) 表示 \(i\) 为根,点集为 \(S\) 的答案,转移加入一棵子树 \(T \subseteq S\) 与其根 \(r\) 并进行更新。复杂度 \(O(3^nn^2)\),常数很小可以通过。
模拟赛 T2
如果体积是 \(2^i\),可以很容易地进行数位 DP 状物,\(f_{i,j}\) 表示考虑了 \(i\) 这一位与更高的位,且要求下一位对这一位进位为 \(j\) 的方案数即可做到线性。
枚举选了几个物品,做上述 DP,这样状态还要记录选了几个数,复杂度 \(O(n^3)\)。
注意到对 \(m\) 做 \(O(n)\) 次 \(+1\) 操作总共只会对 \(O(n)\) 个位进行修改,也就是说每次 \(+1\) 显然有一段前缀答案不变,对后面重新进行 DP 即可。证明考虑势能分析即可。
模拟赛 T3
如果能分解质因数,后面的部分可以简单哈希做到 \(O(n^2 \log V)\),但是我们无法分解质因数。
但是仔细思考我们并不需要知道确切的质因数。我们如果能求出一个集合 \(P\),使得 \(P\) 中任意两个数互质,且每个给定数都能在 \(P\) 中找到分解,那么对 \(P\) 中的数开根到最简后分解因数即可。
我们考虑怎么构建 \(P\)。
依次遍历每个数 \(a_i\),先用 \(P\) 中的数试除 \(a_i\),假设最终得到 \(x\),若 \(x \neq 1\) 则我们需要加入 \(x\)。如果加入 \(x\) 不影响互质,也就是 \(x\) 和 \(P\) 中任意一个数互质,直接加入就行。否则找到某个 \(y \in P\) 且 \(\gcd(x,y)>1\),删除 \(y\) 并加入 \(\gcd(x,y),\dfrac{x}{\gcd(x,y)},\dfrac{y}{\gcd(x,y)}\) 即可。
复杂度应该可以分析到 \(O(n^2\log^2V)\),做完了。
CF735E
限制相当于对于每个点 \(i\),离 \(i\) 最近的染色点距离不超过 \(k\)。
对于每个 \(i\),考虑记 \(d_i\) 表示离 \(i\) 最近的染色点距离,考虑每一组 \(d_1,d_2,\cdots,d_n\) 至多对应一种染色方案,每种染色方案也恰对应一组 \(a\),故考虑对可行的 \(d\) 计数。
什么样的 \(d\) 存在一种对应的染色方案呢?充要条件是:
- 相邻两个的 \(d\) 差值不超过 \(1\)。
- 对于所有 \(d_u \neq 0\),存在邻点 \(v\) 使得 \(d_v = d_{u}-1\)。
必要性容易证明,充分性考虑对于 \(d\) 的值从小到大归纳。
于是可以直接 DP,记 \(f_{i,j,0/1}\) 表示以 \(i\) 为根子树,\(d_i = j\),是否存在 \(i\) 的儿子 \(v\) 使得 \(d_v = j - 1\),转移是容易的,复杂度 \(O(nk)\)。
模拟赛 T1
我们希望选若干点是不好的,剩下点是好的,考虑怎么样的选点符合条件。
显然选的不好的点必然是独立集,容易注意到将这些点标的权值设为 \(1\),其余点标的权值设为 \(2\) 即符合要求,所以这是充要条件。于是可以发现 \(k\) 不重要,可以认为 \(k=2\)。
二分答案 \(x\),每个点权值减去 \(x\),变为求最小权独立集,由于左侧向右侧连边为区间,所以对右侧进行 DP,\(f_i\) 表示最后选了 \(i\) 的最小值,转移有 \(f_i = \min \limits_{j} \{f_j + g(j+1,i-1)\}\),\(g(l,r)\) 是左侧点区间包含于 \([l,r]\) 的点的权值和。容易使用线段树优化,复杂度 \(O(n \log n \log V)\)。
模拟赛 T2
枚举 \(j-i+1 = y\)。
考虑 \((i,i+y-1,k)\) 符合条件的转化。称关键点为所有 \(s_i \neq s_{i-y}\) 的 \(i\),将 \([i,k]\) 每 \(y\) 个分一段,则除了第一段的每段内至多只有一个关键点。
如果能求出所有关键点,那么对着关键点扫描线,只需要考虑相邻两个关键点 \(x,y\) 对区间的贡献,可以用线段树维护 \(l \bmod y\) 的每个余数的左端点最小值,问题变为区间覆盖区间求和,容易维护。
但是关键点数量太大,后面的我也忘了,再想想。
模拟赛 T3
咕咕咕。
CF2046D
首先缩点成 DAG,每个点新点权为 SCC 内点权和。
考虑网络流,将流视为一个人,要求每个点最多从源点获得 \(a_i\) 流量,并且只有从其他点获得过流量或者从源点获得了 \(1\) 的流量才能把 \(a_i - 1\) 个人流进去。拆点可以转化为有下界最小费用可行流,当然这个题中可以将有下界的边合理设计费用避免使用上下界费用流。
CF1815F
每个三元环如果填了 \(1,2,3\),三个点可以分别获得 \(3,4,5\)。
对于每个三元环,将三个点权先加上 \(3\),变为加上 \(0,1,2\)。
等价于给所有无向边定向,使得每条边两端点的入度加上点权不同。
每次贪心选目前点权加入度最小的点并往外定向即可。
模拟赛 T1
区间 DP,注意到计算一个区间 \([l,r]\) 中 \(k\) 获胜的概率只需要将 \([l,k]\) 和 \([k,r]\) 中 \(k\) 获胜概率乘一起,也就是两边是独立的。
整个过程看着很像区间 DP,根据上述结论只需记 \(f_{l,r}\) 和 \(g_{l,r}\) 分别表示区间 \([l,r]\) 中 \(l\) 和 \(r\) 获胜概率,以 \(f\) 为例,转移枚举 \(l\) 最后一次和谁战斗,直接做是 \(O(n^4)\),式子容易拆出来变成 \(O(n^3)\),即可通过。
模拟赛 T2
\(m=0\) 时,显然可以从前往后贪心,过程形如初始有变量 \(s=0\),\(x=0\),枚举 \(i\) 从 \(1\) 到 \(n\),\(s \gets s+a_i\),然后若 \(s<l_i\),则 \(x \gets x + l_i -s\),\(s \gets l_i\)。若 \(s > r_i\),则 \(x \gets x + s - r_i\),\(s \gets r_i\)。最终 \(x\) 即为答案。
将每个 \(l_i\) 和 \(r_i\) 减去 \(\sum \limits_{j=1}^i a_j\),删去贪心过程中的 \(s \gets s + a_i\),这样就变成 \(s\) 每次往这个区间中靠,维护移动距离和。
可以发现对于不同的初始值 \(s\),最终的答案会形成三段分段线性函数,线段树维护。区间反转只需要记录反转前和反转后的分段函数即可。
模拟赛 T3
考虑对于 \(x,y\) 进行判定,分类讨论,二维数点,后面忘了。
CF348E
显然对于每个点来说,删去后这个点会寄的的那些点必然是从这个点出发的一条路径,其实就是这个点到所有关键点最远的那些路径的交。
换根 DP 可以很容易求出,然后树上差分即可。理论可以做到线性。
CF382E
树上最大匹配一般考虑 DP,记 \(f_{i,0/1}\) 表示点 \(i\) 的子树,\(i\) 没选或选了的最大独立集。类似 DP of DP,把这个东西记录到状态里可以转移,但复杂度不对。注意到 \(|f_{i,0}-f_{i,1}| \leq 1\),所以有效状态数是对的,可以通过。
CF2064E
首先必然有 \(c'=c\),因为第一列固定。
把过程想象为从左到右每一列,我们会删掉 \(p_j=i\) 的 \(j\),显然我们只能删掉目前 \(j\) 所在同色连续段内的位置,所以维护一下连续段即可。
ARC176E
考虑最小割模型。
对于每个 \(x_i\) 和 \(y_i\),建立一条链,割掉某条边有对应权值,对于大于等于某个数的要求就直接连一条过去的边表示必须在后面割。
对于 \(a\) 来说,建一个虚点并类似上述这样连一下即可。
QOJ9915
模糊匹配是很难的,考虑 bitset。
对于每个中点我们可以二分,问题变为快速判定一段区间是否在定义下回文。
记 \(f_{l,r}\) 表示区间 \([l,r]\) 是否可行,则 \(f_{l,r} = f_{l+1,r-1} \land |a_{l}-a_r| \leq k\)。
枚举 \(r\),对 \(f_{l,r}\) 做 bitset 即可做到 \(O(\dfrac{n^2}{w})\) 时间,但是空间过不去。
只对 \(l=xB\) 的位置储存结果,取 \(B=\sqrt{n}\) 可以通过。
CF1909G
注意到 \(|y| \mid m-n\),因为 \(m-n\) 就是 \(t\) 中 \(y\) 数量减去 \(1\) 乘以 \(y\) 长度。
枚举 \(|y|\),这部分是 \(O(\sqrt m)\) 的。
考虑 \(y\) 在两个串中出现位置,不难发现 \(x+y\) 必然同时是 \(s,t\) 的前缀,\(y+z\) 必然同时是 \(s,t\) 的后缀。
找到 \(s,t\) 的最长公共前缀与最长公共后缀,则对于 \(y\) 来说有一个区间范围。
事实上我们可以证明所有符合区间范围的 \(y\) 要么同时合法要么同时不合法。证明考虑将 \(y\) 向后移动一位,我们只需要新增的位置相同,所以结论正确。
枚举 \(|y|\) 后只需要判定任意一个 \(y\) 是否合法就行,哈希维护,需要等比数列求和。复杂度 \(O(m+\sqrt{m}\log{V})\)。
P9482
考虑比较区间 \([i,i+l-1]\) 与 \(R([i+l,i+2l-1])\),直接想法是我们只需要比较一个前缀和一个后缀字典序,将 \(s\) 反转后拼接到后面变为后缀字典序比较,SA 后显然可以转化为二维数点。
但是如果 \([i,i+2l-1]\) 是回文串,这个东西就寄了。枚举回文串分界点,求出回文半径后可以也变为二维数点。复杂度 \(O(n \log n)\)。
模拟赛 T1
以左上角为根,每个点深度显然是 \(x+y-2\),所以我们只需要求两点 LCA。
数据随机,每个点到根拐弯次数是 \(O(\log n)\) 量级,分析与前缀 \(\min\) 个数类似。
ST 表二分即可做到 \(O(n \log^2 n)\)。
模拟赛 T2
SAM,DDP。
模拟赛 T3
咕咕。
CF1704H1
对于一个 \(b\),考虑哪些 \(a\)是合法的。
对于每个点 \(i\),若 \(b_i \neq i\),则连边 \(i \rightarrow b_i\)。显然图中不能存在环,此时对于每个 \(b_i \neq i\),有 \(a_{b_i} = i\),可以发现图由若干条链组成,每条链除了链头,其余点的 \(a\) 都已确定。对于每条链,要按照链长是否至少为 \(2\) 分类讨论,预处理一个 DP 后组合数计算,复杂度 \(O(n^2)\)。
P11746
\(2 \mid n+m\) 时无解。
有一个显然的二项式反演。记 \(f_i\) 为恰有 \(i\) 行列完全相同的方案数,\(g_i = \sum \limits_{j \geq i} f_j \dbinom{j}{i}\),\(g_i\) 容易计算,枚举 \(a+b=i\) 表示 \(a\) 行 \(b\) 列全相同,若 \(a, b>0\) 则式子大概是 \(2\dbinom{n}{a}\dbinom{m}{b}2^{(n-a)(m-b)}\),\(a=0\) 或 \(b=0\) 需要特殊考虑,但也是容易的。
求出 \(g\) 后对 \(f\) 二项式反演即可得到一个平方做法。
把式子具体写出来,大概是 \(\sum \limits_{2 \mid x} \sum \limits_{y \geq x} (-1)^{y-x}\dbinom{y}{x}g_y\)。\(y\) 固定时有 \(\sum \limits_{x\leq y,2|x} (-1)^{y-x}\dbinom{y}{x} = -((-2)^{y-1})\)。如果直接枚举 \(y\),发现 \(g_y\) 并不容易快速算,但是可以枚举 \(a\),对于 \(b\) 来说可以发现是一个二项式展开的形式,最终大概是 \(-\sum \limits_{a} \dbinom{n}{a}(-2)^{a-1}(-2+2^{n-a})^m\) 直接计算即可,对于 \(a=0\) 或 \(b=0\) 需要特殊计算,复杂度 \(O(Tn\log n)\)。
QOJ10101
将不出现在序列中的数从大到小排序插入到后面,可以发现此时两个 LIS 差不超过 \(1\)。如果已经相等就做完了,否则考虑翻转答案的一段区间,使得对应的 LIS 增加 \(1\),这部分可以枚举区间左右端点并通过之前维护 LIS 的 DP 结果,有效区间只有 \(O(m)\) 个,对每个区间做一个判定即可。
QOJ10102
对于每个位置首先希望求出白格最小值,如果白格需要的更多那么可以按照顺序删掉一些黑格。
白格形态可以手玩一下,大概是若干偶数行和中间连接的一些格子,可能有许多分讨?
ARC193B
断环为链并考虑断掉边,断边后是一个 DP,比较容易维护。
ARC193C
考虑判定矩阵合法,每次删去一个十字,判断最终能否删空。
进一步等价于第一次选择若干颜色相同的行以及若干列,要求每列除去选定行外颜色相同,且至少有一列的所有颜色和选择的行颜色都相同。然后每次删掉矩阵某相同颜色的行或列,直至删空。
对于计数问题,考虑钦定一个选择顺序,第一次选择所有可行的行与列,然后每次删去所有合法的行,然后是列,以此类推。
考虑记 \(f_{n,m}\) 表示 \(n\times m\) 的网格,不存在某列颜色全相同,所有方案数。转移枚举这次删掉的行数量,分类讨论这些行的颜色是否全部相同。如果全相同,发现我们需要另一个状态 \(g_{n,m}\),表示除了满足 \(f\) 的限制外,还需要满足如果某行全相同,则有一种特定颜色不能为这一行的颜色,也就是这一行只有 \(c-1\) 种可行颜色。\(f\) 和 \(g\) 转移封闭,预处理 \(c\) 和 \(c-1\) 的幂次即可做到 \(O(n^3)\)。
QOJ8784
每个小矮人显然独立,问题变为 \(n=1\)。
问一次 \(0\) 点,无论回答什么都是对称的。
我们只需要在前 \(12\) 小时或后 \(12\) 小时找到分界点即可。
对于前 \(12\) 小时,直接想法是每 \(B\) 分钟分一段,然后在后面对应的 \(B\) 分钟内每分钟问一次,\(B\) 取根号,但是略超限制。
前 \(12\) 小时,隔 \(49,48,47,\cdots\) 进行询问即可。
QOJ8790
考虑 Sum Hash。
选定数 \(P\),选出子集模 \(P\) 需要等于 \(10^9 \bmod P\)。
对于序列做背包,选的模数如果比较大可以 bitset 优化,不过也可不用。
还原方案时,如果这个数可以取也可以不取,随机选择。求出 DP 后不断还原方案直至找出解即可。
QOJ8781
看着就很不能做,考虑 bitset。
直接想法是 \(f_{i,j} = f_{i+1,j+1} \land a_i<a_j\),但这样就变成了两段后缀比较。
长度为 \(m\) 的区间限制是麻烦的,考虑优秀的拆分。
对于所有 \(i=km\) 的 \(i\),计算前面区间跨过 \(i\) 的区间对数量。
此时考虑这个区间根据 \(i\) 划分为了一段前后缀,处理前后缀对应的可能的后面区间位置,枚举前缀起点后直接将两部分交起来即可。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号