12月做题记录
12月做题记录
✩ trick
✯ 会大部分,要\(tj\)提示
✬ 会小部分/完全没想到,看了\(tj\)才会
◈ 脑电波
✡ 有某一算法的神秘通用性质
⊗ 待补
- 12月做题记录
- 势能分析/吉司机线段树+历史值
- PAM
- baka's trick
- 更多莫队
CF1725K Kingdom of Criticism
考虑并查集,每次把\([l,r]\)内存在的点都提出来分别挂到\(l-1/r+1\)上然后删除,如果没有\(l-1/r+1\),新建一个点即可
注意到点的级别是\(O(N)\)级别的且增删对某个点都是\(O(1)\)的,所以总复杂度\(O(N\alpha(N))\)
CF1446D2 Frequency Problem (Hard Version)
如果给定的序列就没有绝对众数,那么直接输出\(n\),否则考虑证明:
最终的答案中的众数中一定有原本的序列的绝对众数
如果不满足的话,显然可以把当前区间拓展且不劣
根号做法 ✬
考虑枚举最终的众数的数量,给一个阈值\(B\),那么直接双指针维护即可得到每个左端点对应的最大的右端点
这里的复杂度是\(O(BN)\)的
考虑当数量\(>B\)时,此时同样为众数的其他数值只有\(O(\frac NB)\)个,现在再来枚举同为众数的数值
设最初的绝对众数为\(A\),现在枚举的另一个为\(B\),只需要给一个序列\(c_i\)赋值为\(c_i=\left\{\begin{aligned}&1&&a_i=A\\&-1&&a_i=B\\&0&&otherwise \end{aligned} \right.\),那么只需要满足一个区间内的\(c_i\)的和为\(0\)即可,这个用前缀和即可处理
当然有可能会出现当前区间内真正的众数既不是\(A\)也不是\(B\)的情况,但显然这种情况是劣的,所以不管,复杂度\(O(\frac NBN)\)
取\(B=\sqrt N\),则总复杂度\(O(N\sqrt N)\)
线性 ✯✩
显然,如果我们依旧是枚举另一种值\(B\),那么只需要找到最长的区间使得\(A\)的数量和\(B\)的数量相同,若他们不是这段区间的众数,那么这段区间一定劣
对于一个\(l\),发现我们的最优区间\([l,r]\)满足\(a_{l-1}=A/B\),\(a_{r+1}=A/B\)且\([l,r]\)内的\(A\)、\(B\)数量相等,若依旧沿用上面提到的\(c_i\),注意到区间和的变化是连续的,也即说明,对于\(r'>r\),那么\([l,r']\)一定全\(>0\)或全\(<0\)
考虑这样一种方法,枚举\(B\)的位置\(x\),每次把\(x\)且没被标记的\(A\)的后继给标记,然后还原,然后再标记前驱,这里其实顺序无所谓,怎么弄都是那些点
显然此时从没被标记的\(A\)一定不会出现在最终的区间\([l,r]\)中,那么显然现在只有\(O(|A|)\)个点,直接用上面的\(1/-1\)的方法即可
只需要记录\(pre_i\)表示\(\leq i\)的\(A\)的最大位置和\(suf_i\)表示\(\geq i\)的\(A\)的最小位置即可做到线性
复杂度\(O(N)\)
ARC186E Missing Subsequence
即使是学了两周\(whk\)的唐诗也能战胜的题目
如果要去\(check\)一个\(\{A_i\}\)是否合法,显然考虑贪心的去\(check\),具体的,首先找出\(1\sim n\)在\(\{A_i\}\)中的第一位,设为\(p_i\),显然需要满足\(A_{p_i\sim n}\)有所有的长度为\(M-1\)的\(1\sim k\)的可重排列,如果\(p_i=x_1\),还要满足不存在恰好等于\(X_{2\sim M-1}\)的可重排列
显然\(p_{x_1}\)是所有\(p_i\)中最大的,考虑枚举出\(p=p_{x_1}\),那么现在就是递归子问题了
- 如果\(x_1=x_2\)
此时加上\(x_1\)后,所有的长度为\(M-1\)的\(1\sim k\)的可重排列就存在了,那么\(1\sim p-1\)就只需要满足所有非\(x_1\)的数都出现过即可
- 如果\(x_1\neq x_2\)
此时\(x_1\)前面还要放个\(x_2\),然后在这个最靠后的\(x_2\)之前,所有非\(x_1\)的数都要出现(\(x_2\)也要再出现)
直接\(dp\)即可,复杂度就\(O(N^2M+NK)\)
ARC179F All the Same ✯✩
很牛的构造
首先有一些显然的性质:
答案代价一定\(\geq0\),只要\(A\)操作一直放到\(1\)位置,\(B\)操作一直放到\(3\)位置即可
设\(a_i\)表示\(\leq i\)操作的有几个\(A\),\(b_i\)同理,那么可能会贡献的位置\(i\)一定会满足:
- \(a_i+b_i\equiv0\mod3\)
- \(b_i\equiv0\mod2\)
- \(2a_i\geq b_i\)(否则\(a_i\)的变化跟不上\(b_i\)的)
显然这是合法的必要条件,猜测是充要的
若设\(v_i=2a_i-b_i\),那么上述条件可以转换为找到一组下标\(p_i\),满足\(v_{p_i}\geq 0\)且\(v_{p_i}\equiv0\mod6\),也即\(p_i\sim p_{i+1}\)之间能拼出平的段,注意到第三个条件是对每一个小段都成立的,那么只需要满足\(v_{p_i}\leq v_{p_{i+1}}\)即可
那么现在只需要找出最长不下降子序列即可
考虑如何构造方案,也即证明它的充分性
还是按照\(A\)操作放到\(1\)位置,\(B\)操作放到\(3\)位置的基本思路,考虑如果调整
因为该区间内的\(2a-b\equiv0\mod6\),设这个值为\(ed\),其实也就表示着\(p_1-p_3\)的值,那么只需要考虑如果给\(ed-6\),如果我们能保证找到一种方法恰好减了\(\frac{ed}6\)次\(6\),那我们的\(\Delta\)最终会变成\(ed\),也就是\(0\),就合法了
考虑在当前操作为\(A\)且\(\Delta=4/5\)的时候特殊操作一次,显然只要在\(ed\neq0\)的情况下每次都这样操作,一定能使得恰好减\(\frac{ed}6\)次\(6\)
- \(\Delta=4\)
此时形如:
|
|
只需要把当前这次的操作给\(2\),然后再交换\(1\)和\(3\)的位置即可
| |
- \(\Delta=5\)
此时一定形如(即上一次操作一定也是\(A\))
|
|
| —— ——
只需要把这次和上次的分别给\(2\)和\(3\)即可
| |
| —— ——
P11393 [JOI Open 2019] 送金
这算蓝题吗(思考),感觉还是>蓝题的吧
以下自动忽略对下标的取模,可能会出现直接用\(A_i\)代替\(A_i-[A_i\%2\equiv1]\),也即有些地方的\(1\)的差可能会被直接忽略
考虑设\(x_i\)表示\(i\)最终共给了\(i+1\)多少钱,有\(n\)个等式:\(A_i+x_{i-1}-2x_i=B_i\)
考虑用\(x_1\)表示出所有的\(x_i\),转一圈表示回来发现会形如\(x_1=\frac{x_1+b}{2^k}\),那么可以解出\(x_1\),顺带着解出所有\(x_i\)
首先肯定要\(x_i\geq0\),光这个肯定不行,然后考虑怎么\(check\)
首先有个贪心,发现如果\(x_i\)还有剩余且\(A_i\geq2\),那么一定是能让\(x_1-1\),\(A_i-2\)就这样做,因为在任何时候进行这样的操作都没有影响,所以越早越好,那么直接这样贪心就可以\(check\)了
但是随便乱搞复杂度肯定不对,于是尝试找出一种策略使得复杂度可接受
对于一个点\(i\),每次肯定向下传\(\min(2x_i,A_i)\),那么分别考虑\(2x_i\leq A_i\)和\(2x_i>A_i\)的情况
发现对于前者,此时可以直接把\(x_i\)清空,且让这\(2x_i\)一直向下传,最环情况是一直传到不能再传,所以是\(O(logV)\)的
对于后者,和前者结合起来看,然后得到这样一种策略:
遍历\(i\),若\(x_i\)有剩余且\(A_i>1\)的点\(i\),然后直接把\(\min(2x_i,A_i)\)往后传,直到不能传为止,那么复杂度是\(O(NlogV)\)的
因为可能有\(1\)的残留之类的,要多转一圈
发现实际上没有必要求出\(x_i\)然后以\(x_i\)为基准来删数,只需要在\(A_i>B_i\)时,就贪心的删,然后转两圈,复杂度就是\(O(N)\)的
木桶效应 ✯✩
称有固定值的点的列和行为特殊的
最基础的想法肯定首先从小到大填入数,设考虑\(dp[i][j][s]\)表示填了\(1\sim i\),占了\(j\)个列,其中占了特殊列的集合为\(s\)
转移要容斥,普通行的好弄,考虑特殊行,如果它们存在点固定为\(i\)且这个点刚好在新增的列中,那么方案为\(1\),否则为\(0\),若存在固定点\(>i\),那么要把固定点占的列给留出来
直接转移复杂度\(O(N^44^qq)\),转移的状态合并一下能优化成\(O(N^34^qq)\)
话说\(4^q\)是枚举子集的子集的复杂度,很牛口牙
正解的话要考虑转换一下,变为求对于所有序列\(\{x_i\}\),满足\(\forall i,\min a_{i,j}>=x_i\)的\(\{a_{i,j}\}\)的数量
依旧设\(dp[i][j][s]\)表示填了\(1\sim i\),占了\(\{x_i\}\)的\(j\)个位置,其中占了特殊列的\(s\)
对于同一行考虑,设将\(x_i\)按从小到大排序,考虑将\(a\)从小到大排,那么方案为\(\prod_i\frac{(i-(x_i-1))!}{(i-(x_{i+1}-1))!}=\prod_i(i-x_i+1)\)
设\(num[s][p][i]\)表示\(s\)集合中\(p\)这一行值\(\geq i\)的限制个数,如果限制存在必填\(i\)则方案为\(1\),否则为\(i-x_i+1-num[s][p][i]\)
转移方程\(dp[i][j][s]=\sum_{k=0}^j\sum_{t\subset s}dp[i-1][k][t]C_{n-k}^{j-k-(|s|-|t|)}(\frac{(j-i+1)!}{(k-i+1)!})^{m-q}\prod_{p=0}^{q-1}\frac{(j-i-num[s][p][i]+1)!}{(k-i-num[s][p][i]+1)!}\)
发现这个转移式中,\(s\)和\(t\)的转移系数,要么独立,只有\(|s|-|t|\),那么按\(|t|\)分类,然后高维前缀和
复杂度\(O(n^32^qq^2)\)
P11402 [Code+#8 初赛] 图 ✡✯✩
差点以为在学高中数学的函数
考虑最多的边数\(m_{max}\),手模一下可以发现\(m_{max}\leq n\),如果\(m>n\),则\(\sum deg_i=2m>2n\),那么一定存在某个点的的\(deg>2\),可以发现,此时所有和该点相连的那些点都不能再有连边,否则就可以找到长度为\(3\)的简单路,那么可以递归到子问题\((m-deg_i,n-deg_i-1)\),显然子问题也是这样的,最后会还有\(m\)但\(n=0\),显然不合法了
考虑什么时候\(m_{max}=n\),说明每个连通块都是基环树,显然\(n\%3=0\)时,建出\(\frac n3\)个三元环即可,\(n\%3=1/2\)时,就不存在合法的构造了
所以\(n\%3=1/2\)时,就是一堆三元环+一个菊花
考虑对三元环计数,\(f(n)\)表示\(3n\)个点构成\(n\)个三元环的方案数,考虑经典\(trick\)看\(3n\)在的环的样子,则有\(f(n)=f(n-1)\times C_{3n-1}^2\)
则答案就是\(\sum_{i=0}^{\lfloor\frac n3\rfloor}f(i)\times C_n^{3i}\times(n-3i-[n-3i==2])\)
\(n\)是\(3e7\)范围的,所以考虑线性的预处理出所有的答案
求出\(f(i)\)的表达式,初始有\(f(1)=1\),根据高中数学知识可以累乘起来得到
那么\(ans\)中显然后面那个\([n-3i=2]\)至多只会满足一次,单独计算即可,考虑剩下的部分\(\sum_{i=0}^{\lfloor\frac n3\rfloor}f_iC_n^{3i}(n-3i)=n!\sum_{i=0}^{\lfloor\frac n3\rfloor}\frac{n-3i}{6^ii!(n-3i)!}\),想尽量合并含\(i\)的式子,把分子弄下去,\(n-3i=0\)时弄不下去,但是可以发现,\(n-3i=0\)时这个值是\(0\),所以现在变成\(n!\sum_{i=0}^{\lfloor\frac{n-1}3\rfloor}\frac1{6^ii!(n-3i-1)!}\)
设\(g(n)=\sum_{i=0}^{\lfloor\frac n3\rfloor}\frac1{6^ii!(n-3i)!}\),则\(ans=n\times g(n-1)\),考虑继续处理\(g(n)\)
因为分母有\(n-3i\),考虑\(g(n-3)=\sum_{i=0}^{\lfloor\frac n3\rfloor-1}\frac1{6^ii!(n-3(i+1))!}=\sum_{i=1}^{\lfloor\frac n3\rfloor}\frac1{6^{i-1}(i-1)!(n-3i)!}=\sum_{i=1}^{\lfloor\frac n3\rfloor}\frac{6i}{6^ii!(n-3i)!}=\sum_{i=0}^{\lfloor\frac n3\rfloor}\frac{6i}{6^ii!(n-3i)!}\)
想去掉分子的\(6i\),再来考虑\(g(n-1)=\sum_{i=0}^{\lfloor\frac{n-1}3\rfloor}\frac1{6^ii!(n-3i-1)!}=\sum_{i=0}^{\lfloor\frac{n-1}3\rfloor}\frac{n-3i}{6^ii!(n-3i)!}=\sum_{i=0}^{\lfloor\frac n3\rfloor}\frac{n-3i}{6^ii!(n-3i)!}\)
那么\(\frac{g(n-3)}2+g(n-1)=n\times g(n)\),所以得到\(g(n)\)的递推式\(g(n)=\frac{\frac{g(n-3)}2+g(n-1)}n\)
复杂度\(O(N+Q)\)
P11405 [RMI 2020] 秘鲁 / Peru ✩
一种类似baka's trick的维护双端队列的方式
显然可以拆成一些长度\(\leq k\)的不交的区间,权值就是每个区间内的最大值之和
转移有\(f(i)=\min_{i-k\leq j<i} f(j)+\max(a_{j+1},a_{j+2},...,a_i)\)
\(O(NlogN)\)显然单调栈+线段树维护即可
讲下\(O(N)\)的做法,依旧还是要维护\(\max\)的单调栈,再考虑维护一个双端队列表示所有合法决策
对于\(\max(a_{j+1},a_{j+2},...,a_i)\)相同的一个区间的\(j\),在栈中只保留区间最左侧的肯定最优
发现我们的双端队列需要的操作有:弹出队尾,弹出队首,在队尾加入数,在队首加入数,询问队列中最小值
直接维护显然不能线性,类似baks's trick的,我们可以维护两个栈,这个双端队列就等于 第一个栈的栈尾到栈首+第二个栈的栈首到栈尾,这样只需要维护栈中每个元素到栈首的\(\min\),再把两个的栈尾的值取\(\min\)即可得到答案
但是可能在弹出的时候发现某一个栈空了,那么我们只需要在两个栈的元素数量\(\geq2\)且其中一个为空时,暴力重构一下这两个栈,分别分一半到每个栈中即可
复杂度\(O(N)\)
[USACO24OPEN] Splitting Haybales P ✩
在线\(O(NlogN)\)做法(用了性质)
疑似太牛的做法
神人官方题解还给\(st\)表卡个\(O(N)\)的空间,做法:https://codeforces.com/blog/entry/74847
虽然确实不管\(a_i\)的不增性质可能更好做,有平衡树和分块的做法,前者目前看到的都是离线的,后者在线
考虑对于一个询问\(x\),设\(x<0\),对于一开始的操作,都是\(x+=a\),假设点\(p\)之后,就变成\(x-=a\),\(x+=a\),\(x-=a\),\(x+=a\)...,直到点\(q\),使得点\(q\)的操作和点\(q+1\)的操作相同
我们把从开始到\(q+1\)看作一组操作,发现此时\(x\in[-(a_q-a_{q+1}),a_q-a_{q+1}]\),我们记\((pos,w)\)表示以\(pos+1\)为第一次操作,初始为\(w\)
发现对于所有的\(i\)作为一组操作的结尾,即下一组操作的开头时,只有\(O(\sum_i 2(a_{i-1}-a_i))=O(V)\)个二元组,我们对这\(O(V)\)个二元组算出他们向后跳一组操作后到达的二元组,然后再\(st\)表处理一下
那么在询问的时候,显然可以二分出当前的\(p\)和\(q+1\),然后我们跳到\(q+1\),就能得到一个预处理过的二元组,然后用\(st\)表能得到当前询问在边界之前到达的最后的那个操作组,然后再用二分出\(p\)和\(q+1\)得到真正的答案
那么就可以做到在线的\(O(NlogN)\)
在线\(O(N\sqrt N)\)做法(不用性质) ✩
考虑先二分出第一次改变\(x\)正负的位置,显然这之后\(x\)都属于\([-V,V]\)的范围
那么可以分块,然后维护\([-V,V]\)跳了每个块最终的值,询问就跳整块+暴力跳散块就好
维护每个块的\([-V,V]\)的最终值,可以把点放到数轴上,类似我以前好像是讲杂题讲到过的\(arc\)还是\(agc\)的题来着,发现对于\(u\)和\(-u\),显然它们最终到达的值一定是相反数,所以每次可以把数轴中数量更少的那一半的数挂到另一半上去,然后另一半的操作相同,都是同时加某个数或同时减某个数
复杂度\(O(Q(\frac NB+B)+V\frac NB+N)\)
离线\(O(NlogN)\)做法(不用性质)
离线下来按\(l\)排序,然后每次在\(l\)处插入询问
那么操作就相当于一部分区间加,剩下的区间减,那么把\(\leq 0\)的分离出来加,剩下的减,再合并回去就好
复杂度\(O(NlogN)\)
[省选联考 2023] 城市建造 ✩✡
显然每个点双都是要么不删,要么全删的
建出圆方树,考虑枚举每个最终的连通块的大小为\(a\) or \(a+k\)
设连通块有\(p\)个,则显然最终连通块的大小必须是\(\lfloor\frac np\rfloor\)或\(\lceil\frac np\rceil\),则\(a\)只有\(\sqrt n\)种取值
那么就可以直接枚举\(a\),然后在圆方树上\(dp\),对于一个要删的\(scc\),枚举里面的点\(x\),考虑它的子树的大小,显然\(<a-1\)的不可能删,\(>a+k-1\)的一定要删,对于等于\(a-1\)或\(a+k-1\)的,显然如果出现这种情况,则其他子树都必须删(大小为\(1\)的可能不用删,提出来单独考虑一下就行)
这样显然能做到\(O(N\sqrt N)\)
但注意到这样做的话,对于很多\(a\),都存在某些点根本有合法的划分子树的方案,显然这时的答案是\(0\)
注意到,每次选子树相当于把子树按大小排了过后选个后缀(对于选\(a-1\)和\(a+k-1\)的比较特殊,相当于再在前面选了一个点之类的),考虑同时对所有\(a\)进行\(dp\),总状态数是\(O(N)\)的,因为每个点只有\(O(deg)\)个状态,那么显然在给\(x\)的状态\(a\)进行转移时,只需要从大到小转移\(a\),然后后缀就是越取越多的,然后每次启发式合并状态,总复杂度度就是\(O(NlogN)\)的了
很有趣的优化口牙!
[AGC008F] Black Radius
考虑怎么不重不漏的计数所有能成为答案的连通块
用\(d\)最小的那个来代替,那么对于一个连通块,它的\(d\geq dis(u,v)\),其中\(u,v\)属于当前连通块
假设所有点都是喜爱点,考虑要知道哪些连通块可以用它来表示
先不考虑\((x,d)\)就是整棵树的情况,显然这个即使取最小的\(d\)也可能有好几个\((x,d)\),所以最后直接给答案\(+1\)即可
而可以发现,只要不是一整棵树的,连通块中就必存在一个点\(p\),满足其存在某一相邻的点不在连通块中,再根据\(d\geq dis(u,v)\)(\(u,v\)属于连通块中),而且一定会有\(u\) or \(v\)就是\(p\),设是\(u=p\),那么\(x\)就会取\(p\)和\(v\)的中点,如果有两个中点,显然会取靠近\(v\)的(因为此处的连通块是合法的,所以这样一定没问题且是唯一的方案),就可以得到唯一的\((x,d)\),
若当前点\(x\)有至少两个子树没填满,那么显然当前连通块的就是\((x,d)\),而恰好只有一棵子树没填满时,也是用\((x,d)\)表示,而恰好只有一棵子树没填满后的\(d+1\)也是满足的,那么也就是,找到以\(x\)作为整棵树的根时的每个子树\(y\)的距离\(x\)最远的点的距离\(d_y\),则取最大的\(d_y\)为\(d_1\),次大的为\(d_2\),那么合法的\((x,d)\)只要满足\(0\leq d\leq \min(d_1-1,d_2+1)\)即可
再来考虑某个点\(x\)不是喜爱点的情况,考虑它的那些\(d\)中,哪些是可以被代替的,可以发现,同样找到以\(x\)作为整棵树的根时的每个子树\(y\),只要\((x,d_0)\)覆盖了整个的某个子树\(y\)且\(y\)中存在喜爱点,那么\(d\geq d_0\)就都可以被替代了
证明的话,显然这是充分的,考虑必要性,如果\(y\)子树中存在点没被覆盖,显然用喜爱点替代后会导致那个点被覆盖,所以不合法
复杂度$O(N)
势能分析/吉司机线段树+历史值
「雅礼集训 2017 Day1」市场 ✡
势能分析,设一个区间的势能为\(log_d(mx-mn)\),对于每次整体除,如果区间内所有数都满足\(\Delta=x-\lfloor\frac xd\rfloor\)相同,那么直接打区间加的\(tag\),实际上这里只需要判是否\(mn\)和\(mx\)满足\(\Delta\)相同即可,如果它们满足,那么其他的数也都一定满足
那么我们整体除的操作每次一定会让遍历中的节点的\(log_d(mx-mn)\)减少\(1\),且显然整体除的过程中的操作除了遍历到被完全覆盖的点的那\(logN\)步,剩下的就是O(中途节点)的数量
而加法操作会让我们的势能每次增加\(lognlog_dV\),所以总复杂度就\(O(Nlognlog_dV)\)
[HDU5634] Rikka with Phi
\(\varphi(n)\)的变化是\(logN\)的
如果只有取\(\varphi(n)\)的操作,那么每次只要区间里有\(>1\)的数,就递归到底去取\(\varphi\),这样复杂度是\(O(NlognlogV)\)的,因为每个数只需要\(logV\)次变化,而每次变化的代价是\(logN\)的
考虑有覆盖操作怎么办,发现覆盖操作很好的点是能让一个区间内的数都相同,这时我们不再硬取到底,而是若当前区间值都相同,那么改成区间覆盖\(\varphi(n)\)操作
如果没有覆盖,显然这样的策略会比最初的策略优,所以复杂度上界也是\(O(NlogNlogV)\)的,而有覆盖的话,可能会导致,原本是可以直接执行取\(\varphi\)转覆盖的区间不能这样做了,而是要递归到里面被覆盖操作改变了的部分再这样,显然它带来的影响只是多递归了\(O(logN)\)次
让\(n,m\)同阶
总复杂度\(O(NlogN+NlogNlogV)\)
「hdu5306」 Gorgeous Sequence
询问的那两个都是好维护的
对于区间取\(min\)操作,考虑这样的策略,记录区间的\(mx\)和次大值\(mx'\),如果\(x\geq mx'\),不操作,如果\(x\leq mx'\),那么递归下去,否则\(x\in(mx',mx)\),只会影响\(mx\),那么可以直接计算的,且\(mx'\)不变
\(tag\)的维护分成对\(mx\)的和对非\(mx\)的即可
考虑设势能为区间内的颜色的种类数,那么每次会递归下去的话,区间内种类数至少会\(-1\),总的种类数只有\(O(NlogN)\)种,所以总复杂度就是\(O(NlogN)\)
[CF793F] Julia the snail
依旧扫描线右端点,记录左端点\(l\)的答案\(dp_l\),那么对于当前右端点\(r\),其对应的绳子的左端在\(to[r]\),那么\(dp\)转移有:\(\forall l\leq to[r]\&\&dp[l]\geq to[r]\),\(dp[l]=r\)
这个就类似于区间取\(min\)也就是上一道题了,用同样的策略,复杂度\(O(NlogN)\)
「BZOJ 4695」最假女选手
复杂度只考虑区间取\(min\)和区间加一起操作的复杂度,因为显然区间取\(max\)和区间取\(min\)在复杂度上互不影响
势能定义为点\(x\)满足其的区间最大值\(<\)其父亲的区间最大值的点的点数,也将这样的点称为关键点
设\(mx[x]\)、\(mx'[x]\)分别表示\(x\)的子树中最大和次大的值,发现\(mx'[x]\)等于\(\max_y mx[y]\),其中\(y\)是\(x\)子树中非\(x\)的关键点
一个点\(x\)会往下递归当且仅当存在\(y\)在\(x\)子树中且是非\(x\)的关键点,使得\(mx[y]\geq x\),显然这轮操作后,\(y\)将不再是关键点
而区间加操作带来的势能增加是每次\(O(logN)\)级别的,所以总势能就是\(O(NlogN)\)级别的,而消除一个势能需要递归\(O(logN)\)层,所以总复杂度是\(O(Nlog^2N)\)的
实际效率是\(O(NlogN)\)的,因为显然不太能跑满
P4314 CPU 监控
发现所有操作可合并为增加+赋值的二元形式,复杂度\(O(NlogN)\)
UOJ164 【清华集训2015】V
一开始用了类似上上道题的方法口牙,然后非常难写,其实也还好,但没网上的做法简洁,而且用上面那种的话复杂度应该是双\(log\)的
发现题目的操作都可以表示为把区间内的数\(x\)变成\(\max(x+v,c)\),那么线段树维护这样的二元组\((v,c)\)即可
合并时,前后整体的操作是\((a_0,b_0)\),\((x_0,y_0)\),分别的最大二元组是\((a_1,b_1)\),\((x_1,y_1)\)
合并得到\((a_0+x_0,\max(b_0+x_0,y_0))\),\((\max(a_1,a_0+x_1),\max(b_1,b_0+x_1,y_1))\)
复杂度\(O(NlogN)\)
P6242 【模板】线段树 3(区间最值操作、区间历史最值)
就是吉司机把区间取最值改成区间加,再加上维护历史值
复杂度\(O(Nlog^2N)\)
[UOJ169] 元旦老人与数列
上面那个变成取\(\max\)且简化的版本
[CF526F] Pudding Monsters
对横坐标扫描线,维护当前\(r\)和每个\(l\)的区间\([l,r]\)中的棋子的高度的\(mn\)和\(mx\),要求\(mx-mn+1=r-l+1\),即维护\(mx-mn+l\)的最小值及个数即可
复杂度\(O(NlogN)\)
[CF997E] Good Subsegments
询问离线下来,然后对右端点扫描线,好的区间\([l,r]\)满足\(mx-mn=r-l\),即维护\(mx-mn+l\)的最小值
记录历史和,打个标记\(tag\)表示让前区间值等于区间最小值的点的代价\(+1\)即可,这道题的\(tag\)因为只传给和它值相同的那个儿子且值会改变,所以我们每次修改值的时候就一段一段的改(对应就是栈的top弹一次改一次),每次就会是一个区间加,那么现在值相同,区间加后依旧相同
复杂度\(O(NlogN)\)
[NOIP2022] 比赛
询问离线,对右端点扫描线,维护两个栈,然后维护区间内的答案、长度以及两种和即可
设\(w_0\)为区间内\(sufmax_a[i]\)的和,\(w_1\)为区间内\(sufmax_b[i]\)的和,\(w_2\)为区间内的\(\sum sufmax_a[i]\times sufmax_b[i]\)
维护如下信息:\(\{a,k_0,k_1,k_2,tag_0,tag_1\}\),表示会使得\(ans+=a\times sz+k_0\times w_0+k_1\times w_1+k_2\times w_2\),其中\(sz\)为区间大小,\(tag_{0/1}\)分别表示最新的修改把\(w_{0/1}\)修改成了什么
然后维护即可
复杂度\(O(NlogN)\)
PAM
CF700E Cool Slogans
首先贪心的策略肯定是\(x_i\)能省去一些多余的字符就省,那么最优情况下\(x_{i-1}\)一定是\(x_i\)的前缀 and 后缀
考虑\(SAM\),那么\(s\)的上一个一定是它的\(fail\)祖先
如果还是要求是前缀,就不好找,但是如果要求的是在\(s\)中出现\(\geq2\)次,那么就很好找了
考虑\(dp[s]\),那么把\(s\)的\(fail\)祖先提出来一定会是一个前缀的满足
但是每个点\(s\)内代表的字符串有多个,实际上只考虑最长的那个就行
作为被转移到的\(s\)时,显然越长越好
作为转移给别人的点时,设为\(t\),假如是\(t\rightarrow s\),且\(t\)的最短串可以,\(t\)的最长串不可以,那么说明\(t\)的最长串在给\(s\)的最长串匹配时会从头出去,考虑设点\(p\)代表\(s\)的最长串前面加上\(t\)的最长串出去的地方,那么\(s\)一定是\(p\)的\(fail\)祖先,说明存在一个\(endpos\),它属于\(s\)不属于\(t\),发现此时会导致\(t\)的最小串在此处出现而\(t\)的最长串没有出现,违背了它们\(endpos\)相同的原则
那么转移的时候用线段树合并来\(check\)即可
复杂度\(O(NlogN)\)
CF932G Palindrome Partition ✬✡
\(PAM\)入门必做题口阿
大部分借鉴自:https://www.luogu.com.cn/article/aytabs1n ,大概用自己的话复述一遍了
首先,原问题等价于求字符串\(s_1s_ns_2s_{n-1}...s_{\frac n2}s_{\frac n2+1}\)的长度为偶数的回文子串的划分方案数
求回文子串的划分方案关系到一堆东西和引理,选了些以前没仔细想过的/不会的写,可能下面提到的有的和这个问题的解法无关
- 弱周期引理
这里的周期\(T\)只需要满足\(\forall i\in[1,n-T],s_i=s_{i+T}\),即不需要满足\(T\mid|s|\)
若\(p\),\(q\)是字符串\(s\)的周期,且\(p+q\leq|s|\),则\(\gcd(p,q)\)也是\(s\)的周期
证明:
设\(p\leq q\),因为满足了\(p+q\leq |s|\),那么对于\(\forall i\in[1,|s|]\)都有\(i\leq |s|-q\)或\(i>p\)
对于前者,有\(s[i]=s[i+q-p]\),对于后者,有\(s[i]=s[i-p+q]\),那么显然又会有个周期\(q-p\),然后就是一个类似\(gcd\)的过程,最后可以得到最小的周期是\(gcd(p,q)\)
- 周期引理
若\(p\),\(q\)为\(s\)的周期,那么\(p+q-\gcd(p,q)\leq|s|\),则\(\gcd(p,q)\)也是\(s\)的周期
懒得证了(
- 字符串\(s\)中存在长度为\(x\)的\(border\) \(\Leftrightarrow\) \(s\)存在长度为\(|s|-x\)的周期
- 若字符串\(s\),\(t\)满足\(|s|\leq|t|\leq2|s|\),则\(s\)在\(t\)中的所有匹配的位置构成等差数列
考虑三个相邻的匹配的位置的间隔分别为\(a\)和\(b\),则定有\(s\)存在长为\(a\)、\(b\)的周期,且\(a+b\leq|s|\),那么更小的周期是\(\gcd(a,b)\),也就是说\(a\)和\(b\)都可以缩小到\(\gcd(a,b)\)
推论:若字符串\(s\),\(t\)满足\(|s|\leq|t|\leq2|s|\),且\(s\)在\(t\)中的所有匹配构成公差为\(d\)、项数\(\geq3\)的等差数列,则\(s\)的最小周期为\(d\)
- 字符串\(s\)的所以长度\(\geq\frac{|s|}2\)的\(border\)组成一个等差数列
- 若\(|s|=|t|\),记\(LargePS(s,t)=\{k|k\geq\frac{|s|}2,pre(s,k)=suf(t,k)\}\),那么\(LargePS(s,t)\)构成等差数列
其实就是找到最大的然后跳\(border\),然后就是上一条引理
推论:我们将字符串\(s\)的所有\(border\)按照长度属于\([2^i,2^{i+1})\),那么分到第\(i\)类的就是\(LargePS(pre(s,2^{i+1}),suf(s,2^{i+1}))\),显然每一类内是个等差数列,所以我们可以讲字符串\(s\)的\(border\)划分成\(O(log|s|)\)个等差数列,且可知任意两个等差数列的值的范围不交
- \(s\)是回文串,则\(s\)的后缀\(t\)是回文串当且仅当\(t\)是\(s\)的\(border\)
推论:\(s\)是回文串,则\(s\)的回文后缀可以被划分成\(O(log|s|)\)个等差数列
- \(slink\)指针
记\(delta[x]=len[x]-len[fail[x]]\),则\(slink[x]\)就是\(x\)跳\(fail\)跳到的第一个\(delta\)和\(x\)的\(delta\)不同的点
显然如果\(x\)一直跳\(slink\),只要\(O(log|s|)\)步,而又因为中间隔着的地方是个等差数列,有些东西就很好维护了
- 回文划分计数
一个个加入字符的同时计算\(dp[i]\)表示\(s[1,i]\)的划分方案
暴力的转移是\(dp[i]=\sum_{j<i}[check(j+1,i)==true]dp[j]\),考虑优化
用\(slink\)指针,那\(PAM\)要维护一个\(g[x]\)表示\(x\)一直跳到顶(即下一步就是\(slink[x]\)的那个位置)的贡献和,发现对于\(i\)在\(PAM\)上\(ins\)时找到的点\(p_0\),设它往上跳到顶经过了\(p_1\),\(p_2\),...,\(p_k\),对应的转移点分别是\(j_0\),\(j_1\),\(j_2\),...,\(j_k\)(\(j_0<j_1<j_2<...<j_k\),因为\(p_0\)是最长的那个),且有\(j_1-j_0=j_2-j_1=j_3-j_2...\),但是我们的时候,发现从当前\(i\)找到的点是\(...,p_2,p_1,p_0\)时刻,分别对应当前的转移点集是\(...,\{j_0,j_1,...,j_{k-2}\},\{j_0,j_1,...,j_{k-1}\},\{j_0,j_1,...,j_k\}\),意味着如果像维护转移,实际上\(p_0\)对应的转移点是最近的那个\(j_k\)
具体看下代码吧,说着有点抽象
那么题目要求了必须是偶长的回文串,那么再加一维变成\(g[x][0/1]\),然后跑\(slink\)合并的时候要关注一下\(delta\)的奇偶性
https://codeforces.com/contest/932/submission/298380996
复杂度\(O(NlogN)\)
P4287 [SHOI2011] 双倍回文
相当于就是找一个回文串\([a,b]\),使得它的长度是\(4\)的倍数且\([\lceil\frac{a+b}2\rceil,b]\)也是回文的
考虑\(PAM\)的时候,每加入一个回文串,可以跳\(slink\)指针,因为注意到要找的是\(fail\)中有没有\(\frac{len}2\)的,而每次跳\(slink\)会让\(len/2\),所以实际只会跳\(O(1)\)次
复杂度\(O(N)\)
baka's trick
baka's trick对于双指针大概就是回滚莫队至于莫队,也可以说是
具体的,可以维护那些,好合并不好删除的操作,若区间\(\gcd\)、背包之类的
具体操作,还是维护指针\(l\),\(r\),以及\(mid\),初始时\(l=r=mid=1\)(即从\(1\)开始扫,当然可以从其他地方扫,灵活应变即可),然后根据单调性或者啥的性质,每次\(++r/++l\),且维护两个栈,第一个维护\(i\in[l,mid]\)的\(calc(i,mid)\),第二个维护\(i\in(mid,r]\)的\(calc(mid+1,i)\),如果\(l>mid\)了,第一个栈和第二个栈都清空,\(mid=r\),并重构第一个栈
设每次计算\(calc\)的复杂度是\(O(w)\)的,那么总复杂度\(O(NW)\)
JZOJ6358. 【NOIP2019模拟2019.9.15】小ω的仙人掌
啥啊,咋看咋像校内题吧,网上的题解咋来的啊
- 题面:给你一个二元组\((a_i,b_i)\)序列,求最小的区间\([l,r]\)的长度,其中\([l,r]\)满足这里面的每个二元组选或不选,使得\(\sum a_i=w\)且\(\sum b_i\leq k\),\(a_i\leq w\leq5e3\),\(k\leq1e9\),\(n\leq1e4\)
如果\([l,r]\)合法,那么\([l,r+1]\)也合法
考虑双指针,如果当前\([l,r]\)合法,则\(++l\),否则\(++r\)
发现背包好合并不好删除,所以考虑baka's trick即可,复杂度\(O(NW)\)
更多莫队
三维莫队:P1903 [国家集训队] 数颜色 / 维护队列
按\((bel[l],bel[r],time)\)排序
则跳\(l\)的复杂度显然是\(O(QB)\)的
跳\(r\)的复杂度是\(O(QB+\frac {N^2}B)\)
跳\(time\)的复杂度是\(O(Q\frac{N^2}{B^2})\)
总复杂度\(O(QB+\frac{N^2}B+Q\frac{N^2}{B^2})\),视\(Q\)为\(N\),取\(B=N^{\frac 23}\),复杂度即为\(O(N^{\frac53})\)
树上莫队:SP10707 COT2 - Count on a tree II
用欧拉序(进来的时候记一次,出去的时候记一次)表示,然后转为序列上的莫队问题,具体就是对于点\(u\),\(v\)(\(st[u]<st[v]\)),若\(u\)和\(v\)呈祖先关系,则询问的\([st[u],st[v]]\),否则问的\([ed[u],st[v]]\)
这里是记录区间中出现次数恰为奇数即\(1\)次的那些点的颜色
复杂度\(O(N\sqrt N)\)
回滚莫队:歴史の研究
其实也可以分块做,维护\(f[i][j]\)表示前\(i\)个块中颜色\(j\)的数量,\(g[i][j]\)块\(i\)到块\(j\)的答案,预处理后即可在线做,复杂度\(O(N\sqrt N)\)
也可以莫队做,得到所有可能的\(a[i]\times c\),有\(O(N)\)个,然后对这些数分块即可,离线,复杂度\(O(N\sqrt N)\)
这题回滚莫队明显吧
二次离线莫队:P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II
首先莫队离线下来,假设在移动\(l\),就是在问\([l,r]\)中有多少\(>a_l\)的数
再把这些询问,共\(O(N\sqrt N)\)个离线下来,拆成\([1,r]-[1,l-1]\),用分块做即可
但是空间要求是\(O(N)\)的,发现莫队的时候,实际上每次给的询问会是\(l\in[l_1,l_2]\),问\([l,r]\)中多少\(>a_l\)的数,然后它们拆后的\([1,l-1]\)之和自己相关,可以一开始预处理,\([1,r]\)的\(r\)都相同,可以一起查询
时间复杂度\(O(N\sqrt N)\),空间\(O(N)\)
二次离线莫队:P5386 [Cnoi2019] 数字游戏
注意到是排列,所以可以对权值这一维进行莫队,然后就是求属于\([l,r]\)中的所有极长连续段,可以分块+链表维护(连续段头和尾互相指),删除难,加入容易,所以回滚莫队
超难写/tuu
复杂度\(O(N\sqrt N)\)
二次离线莫队:P6528 「Wdoi-1」完美冻结
即求\(\sum_{i\in[x_1,y_1]}\sum_{j\in[x_2,y_2]}\lfloor\frac{\sum_{p\in[\min(i,j),\max(i,j)]}a_p}k\rfloor\)
可以拆成前缀和的形式,\(\sum_{i\in[x_1,y_1]}\sum_{j\in[x_2,y_2]}\lfloor\frac{sum_{\max(i,j)}-sum_{\min(i,j)-1}}k\rfloor\),进一步的,\(\sum_{i\in[x_1,y_1]}\sum_{j\in[x_2,y_2]}\lfloor\frac{sum_{\max(i,j)}}k\rfloor-\lfloor\frac{sum_{\min(i,j)-1}}k\rfloor-[sum_{\max(i,j)}\%k<sum_{\min(i,j)-1}\%k]\)
对于\([x_1,y_1]\)和\([x_2,y_2]\)不交的情况,前面部分就很好处理了,而后面只需要拆成\(([1,y_1],[1,y_2])-([1,y_1],[1,x_2))-([1,x_1),[1,y_2])+([1,x_1),[1,x_2))\),然后莫队二次离线即可
对于有交的情况,设交的是\([x_2,y_1]\),可以拆成\([x_1,x_2)\)、\([x_2,y_1]\)与\([x_2,y_1]\)、\((y_1,y_2]\),然后除了\(([x_2,y_1],[x_2,y_1])\)其他的都是不交的,这一组的前面部分也很好算,后面只需套一个莫队二次离线即可
最好写的写法就是全拆成\(([1,r1],[1,r2])-([1,l1),[1,r2])-([1,r1],[1,l2))+((1,l1),(1,l2))\),然后再操作
考虑这时处于\(([1,x],[1,y])\)中的逆序对,设\(x\leq y\),先算出\([1,x]\)中\(i<j\&\& sum_i\%k<sum_j\%k\)的点对\((i,j)\)的数量,然后现在就只需要知道\([1,x]\)中大于\([1,y]\)中的点对数量即可,二次离线莫队,然后还要加上\([1,x]\)作为\(i\),\([1,y]\)作为\(j\)的逆序对数,这样写出来只有\(3kb\)左右啊,上面那种真要每种情况分别写感觉\(6kb\)起步了吧
复杂度\(O(N\sqrt N)\)
回滚莫队:P4477 [BJWC2018] 基础匹配算法练习题
考虑给定了\(\{C_i\}\)怎么做,显然可以贪心,有很多种做法,找一种支持添加进新的\(C_i\)的做法:
每次对于一个\(C_i\),找到最大的\(A_j\)满足\(A_j+C_i\leq Z\)且\(j\)没被标记,然后让\(i\)和\(j\)匹配并标记\(j\)
反证,如果不优,说明存在一种替换方法,找到一个长为\(m\)的二元组序列\(\{(p_i,q_i)\}\)满足\(A_{p_i}\)与\(C_{q_i}\)目前是匹配关系,那么即是对于新加入的\(C_{q_0}\),要求变成\(A_{p_i}\)与\(C_{q_{i-1}}\)匹配(加入了一个\(A_{p_{m+1}}\)且该点不被标记),这样就能说明当前的匹配不优
显然\(A_{p_{m+1}}<A_{p_m}\),否则不符合我们的贪心,且\(A_{p_{m+1}}+C_{q_0}>Z\),注意到所有\(C_{q_i}\)原先匹配的\(A_{p_i}\),现在是\(A_{p_{i-1}}\),若\(A_{p_{i-1}}>A_{p_i}\),则说明\(C_{q_{i-1}}\)一定是在\(C_{q_i}\)之前加入的,一定存在一个\(i\)满足\(A_{p_{i-1}}>A_{p_i}\)且\(A_{p_{m+1}}\in[A_{p_i},A_{p_{i-1}}]\)(这样的\(i\)一定存在,设对于\(C_{q_0}\),其能匹配的最大的是\(A_x\),则一定有\(A_{p_1}\leq A_x\)且\(A_{p_{m+1}}>A_x\),再加上\(A_{p_{m+1}}+C_{q_0}>Z\)的条件),显然在刚加入\(C_{q_i}\)时,它是会匹配\(A_{p_{m+1}}\)而不是\(A_{p_i}\),因此得证
然后这个找的过程用并差集维护就好,对\(A_i\)排序,就如果\(i\)被标记了,就向\(i-1\)合并
那么回滚莫队+n并查集按秩合并即可
复杂度\(O(N\sqrt NlogN)\)
三维莫队:P8930 「TERRA-OI R1」神,不惧死亡
就是让你找到最小的\(>0\)的出现偶数次的数\(a\),设\(b>a\)且\(b\)是最小的,出现过的值,则答案就是\(b\),特判一下出现次数全\(\leq 1\)不合法即可
那么这个显然可以三维莫队+值域分块解决
复杂度\(O(N^{\frac53})\)
二次离线莫队:P5501 [LnOI2019] 来者不拒,去者不追
考虑莫队的过程中,加入一个数\(x\)带来的影响,发现Ans+=比x大的数的和+x*(比x小的数的个数+1)
直接做怎么都得带\(log\),考虑莫队二次离线下来即可
复杂度\(O(NlogN+N\sqrt N)\)
about 二次离线莫队
wc,我突然发现一个细节问题啊,我P5501 [LnOI2019] 来者不拒,去者不追之前写二次离线莫队的时候,都是先把\(l\)指针跑完了再跑\(r\)指针,这样可能会存在\(l>r\)的情况啊,然后前面的题不知道为啥没问题,没细究,可能就是些神秘的东西导致它阴差阳错的对了
为了完全的正确,别担心\(l>r\),所以还是先让\(l\)向左跑,\(r\)向右跑,再跑\(l\)向右和\(r\)向左的
大致框架应该是这样:
op[0].l=1;
for(int i=1;i<=m;++i){
int nowl=op[i-1].l,nowr=op[i-1].r;
if(op[i].l<op[i-1].l){
vecr[nowr].push_back({op[i].l,op[i-1].l-1,i,1});
nowl=op[i].l;
}
if(op[i].r>op[i-1].r){
vecl[nowl].push_back({op[i-1].r+1,op[i].r,i,1});
nowr=op[i].r;
}
if(op[i].l>op[i-1].l){
vecr[nowr].push_back({op[i-1].l,op[i].l-1,i,-1});
nowl=op[i].l;
}
if(op[i].r<op[i-1].r){
vecl[nowl].push_back({op[i].r+1,op[i-1].r,i,-1});
nowr=op[i].r;
}
}

whk恐怖如斯,仅补两周即可让呆猫失去大脑
浙公网安备 33010602011771号