退役前的做题记录3.0
upd on 2020.10.17:
不补前面的咕掉的了,随缘更
upd on 2021.7.29:
博主退役了,没 4.0 了(虽然没退役也不一定有
CF1172F Nauuo and Bug
每个区间\([l,r]\)维护一个数组\(c_x\)表示最小的数经过\([l,r]\)后需要减去\(x\)个\(p\)。
然后我们需要合并两个区间的\(c\)数组。
直接暴力更新的话就是对于\(\forall x,y,c_{x+y}=\min\{c_{x+y},\max\{c_x,c_y-sum_{ls}+xp\}\}\),表示经过了\([l,mid],[mid+1,r]\)的步数是这么多需要的初值。
\(c\)显然单调,但是合并的话还需要\(c_x-sum+xp\)单调,即\(c_x-c_{x-1}\geq p\),这一点比较显然。
线段树上双指针合并一下\(c\)就好了。
code
CF643G Choosing Ads
很有意思的题。
考虑一个求数组中出现次数\(>50\%\)的算法:每次随便选出两个不同数并删掉,最后剩下的那个数就是我们所求的答案。
将这个算法扩展到\(k\%\)就是每次选出\(\lceil\frac {100}k\rceil\)个数,最后剩下的小于\(\lceil\frac {100}k\rceil\)个数就是可能的答案。
线段树每个区间维护这个选择过程即可。
code
CF704D Captain America
不妨设\(R<B\),那么我们就是要尽量选\(R\)。
对于横纵坐标分别建点,那么一个点就相当于\(x\to y\)连边,每个限制就是\(S\to x\)或\(y\to T\)连容量在\([l,r]\)之间的边,对这个二分图跑出的最大流就是最多可选的\(R\)。
code
CF704E Iron Man
以\(t\)为\(x\)轴,\(dfs\)序为\(y\)轴建立坐标系,树链剖分后可以将一条路径转为\(\log\)条连续的\(dfs\)序,一段连续的\(dfs\)序可以看成一条线段。
那么我们现在就是要对每条重链考虑其\(x\)最小的两两直线的交点,考虑扫描线维护。
但是每个直线上的\(y\)坐标时刻变化,我们手头貌似并没有很好的数据结构,其实不然。
对于还未产生交点的某一时刻,下一个交点产生位置一定是相邻的两个\(y\)坐标之间的,而对于所有直线,如果未产生交点的话它的比较方式就和之前时间的比较方式是一样的,直接把当前的\(y\)丢进 \(\text{set}\) 定义一下比较方式就好了,注意如果当前时间过了产生交点的时间就必须 \(\text{break}\)。
这题精度非常卡,建议手写分数类(本人没写导致卡了十几发)。
code
ARC117D Miracle Tree
不知道为什么自己一开始觉得这做法是假的
考虑将所有\(E\)拿出来从小到大排序,假设排序后从小到大的编号为\(p_i\),那么有\(dist(p_i,p_{j})\leq E_{p_{i}}-E_{p_j}\),又因为\(dist(p_L,p_R)\leq \sum_{i=L}^{R-1}dist(p_i,p_{i+1})\),所以我们令\(E_{p_{i+1}}-E_{p_i}=dist(p_{i},p_{i+1})\)肯定是合法的且答案最小,那么最终答案就是\(\sum_{i=1}^{n-1}dist(p_i,p_{i+1})=2(n-1)-dist(p_1,p_n)\),令\(p_1,p_n\)为直径两端,一遍\(dfs\)构造即可。
ARC117E Zero-Sum Ranges 2
首先对于某个序列我们求出它的前缀和,设每种前缀和的数量为\(a_i\),那么最终就是要统计\(\sum {a_i\choose 2}=K\)的序列个数。
考虑dp,通常我们选择的dp状态为从左往右扫描,但是在这题中这样的状态无法转移,所以我们对于前缀和数组所构成的折线,从上往下扫描来设计状态。
(图片来自官方题解)
设\(f_{i,j,k}\)表示目前已经填上了\(i\)个前缀和的位置,\(\sum{a_i\choose 2}=j\),除了两端还有\(k\)个“洞”的方案数。
解释一下“洞”的含义:因为只能填\(0/1\),所以我们转移时当前层每个数旁边肯定要放一个数,而相邻的两个可以共用一个数,所以可以把“洞”理解为除了开头和结尾的相邻的中间还可以放数的地方。
枚举下一层选\(x\)个数可以得到转移:\(f_{i+x,j+{x\choose 2},x-(k+2)}\leftarrow f_{i,j,k}\times {x-1\choose k+1}\)(注意我们没有算开头结尾但是开头结尾实际上也要放)
如果还没有理解的话可以看下下面这张图片(来自官方题解):
最后统计答案就是枚举一个前缀和为\(0\)的分界位置,然后把正负拼到一起,答案就是\(\sum f_{i,j,k}\times f_{2N+1-i,K-j,k-1}\)。
AGC053C Random Card Game
考虑对于给定两堆的答案,假设最后分为了\(A,B\)两堆且\(2N\)这个数在\(B\)中,对于\(A\)中的每个数\(A_i\),记\(j\)为最小的使得\(B_j>A_i\)的位置,令\(d=\max_i j-i\)那么答案为\(N+d\),下面证明这个结论:
必要性显然,充分性考虑从\(d\)入手,当\(d>0\)时,找到使\(j-i=d\)的最小的\(i\)然后做操作\(k=i\)可以使\(d-1\),否则直接从\(i\)最大的开始一个个删就好了。
记\(p(i)\)为\(d\leq i\)的概率,那么最终答案为\(2N-\sum_{i=0}^{N-1}p(i)\),考虑如何算出\(p(d)\)。
最后发现\(p(d)=\prod_{i=1}^{N-d}\frac {2i+d-1}{2i+d}\prod_{i=N-d+1}^N\frac {N+i-1}{N+i}\),组合意义就是每次加入的数除了当前场上最大的都行,然后应为前面的数都是这样子限制的所以可以类似条件概率那样子想(和 \(\mathsf{\color{black}{x}\color{red}{gzc}}\) 讨论了一下发现这样子应该是最好理解的了,如果有更好的理解方式欢迎来锤)。
然后\(O(n)\)算下上面那玩意儿就完事了。
ARC110D Binomial Coefficient is Fun
补上\(A_0=0\),那么就是要求\(\prod _{i=0}^n{B_i\choose A_i},\sum_{i=0}^nB_i=m\)的答案。
考虑\({B_i\choose A_i}\)的组合意义,即\(B_i+1\)个球中间插\(A_i\)个板的方案数。
又因为每对\((A_i,B_i)\)分开考虑再乘起来比较棘手,考虑将总共的\(n+1+m\)个球放到一起考虑。
我们可以新加\(n\)个板表示“分割板”,就是将每个不同的\(B_i\)给分开,那么原来的方案数就是先插\(n\)个“分割板”,再在分成的\(n+1\)段中分别插入\(A_i\)个板的方案数。
容易观察得知,该问题的答案和直接插入\(n+\sum A_i\)的答案相同,那么原问题的答案就是\({m+n\choose n+\sum A_i}\)。
最后\(O(\sum A_i)\)求解即可。
ARC110E Shorten ABC
将\(A,B,C\)看作\(1,2,3\),那么每次操作就是将\(a_i,a_{i+1}\)替换为\(a_i\oplus a_{i+1}\)。
那么我们可以有另一个过程来描述变化:将原串分割成若干段不同的子段,满足每一个子段间异或和不为\(0\)且不全相同,最终得出的新串就是所有子段的异或和。
特判掉字符全部相同的情况,那么问题我们可以将一段相同字符的子段缩起来是等价的,考虑在该限制下统计答案。
自然想到对于一段合法的串\(T\),我们如何去判断它是否能被生成:从前往后贪心匹配,能选择选。
由此设计出一个 dp 状态:\(f_i\)表示\(1\sim i\)能够生成的不同\(T\)的个数,同时记\(nxt_{i,j\in\{0,1,2,3\}}\)表示下一个前缀和为\(j\)的位置,然后转移到\(j\)不等于当前异或前缀和的\(f_{nxt_{i,j}}\),因为该 dp 可以很好的表示上面的贪心过程所以正确。
最后答案就是所有\(i+1\sim n\)异或和为\(0\)的\(f_i\)之和。
ARC110F Esoswap
首先考虑构造出 \(N-1,N-2,...,1,0\),可以从\(p_{N-1}\)到\(p_0\),如果\(p_{N-1-i}\neq i\)就一直对\(N-1-i\)操作,这样子构造的话从大到小仅有\(i\)能改变\(i+1\sim N-1\)的结果(\(<i\)的已经固定在后缀上,\(>i\)的会跳过这段后缀)但是这时候我们会停,所以最后的结果就是排成 \(N-1,N-2,...,1,0\)。
如何还原出\(0,1,2...N-1\)我们考虑\(1\)的特殊性,还是从大到小把每个\(i\)放在对应位置:可以每次将\(1\)挪到位置\(i\),此时\(i\)必定出现在\(0\)位置,再对\(0\)操作就好了,正确性显然。
该构造操作次数为\(O(N^2)\),可以通过。