6月做题记录
CF741C Arpa’s overnight party and Mehrdad’s silent entering
三个的限制不好搞,考虑到两个间的限制好弄,所以把限制放严成\(2i\)和\(2i-1\)不能同色
现在就可以连边所有\((a_i,b_i)\)和\((2i,2i-1)\)
考虑可能不合法就是存在奇环,但是考虑模拟那个环的形成,发现一定是第一种边和第二种边交替的,不可能出现同类边相邻的情况,那就说明环必定是偶环
复杂度\(O(N)\)
loj2816 「eJOI2018」元素周期表
经典的trick,建出行点和列点,然后点\((x,y)\)对应行点\(x\)和列点\(y\)的连边
发现在当前不花代价添加新的节点时,\((x,y)\)能标记当且仅当行点\(x\)和列点\(y\)联通
那么答案就是初始的联通块数\(-1\)
复杂度\(O(N)\)
loj6949「THUPC 2025 初赛」背向而行
很牛的题
首先你手模下能感受到,其实操作顺序是无关,严谨证明如下:
按照题目的,
操作最小的得到的操作序列\(A\),然后再考虑一个按任意顺序操作的操作序列\(B\),满足它最后剩下的数不重显然不会有它们互为彼此的前缀
考虑它们最小的\(i\)满足\(A_i\neq B_i\),显然对于\(j>i\),一定存在\(B_j=A_i\)
让这个\(j\)是满足\(B_j=A_i,j>i\)的最小的\(j\),考虑把这个\(B_j\)插入到\(B_i\)前面,此时显然这个新的\(B‘\)最终得到的序列和\(B\)得到的一样
注意到重复这个过程,就可以让两者的\(lcp\)越来越长,最后得到\(A=B\)
得证
然后还需要一个很重要的东西:
考虑到最后全是\(0/1\),你会想维护\(1\)的连续段,然后你考虑怎么合并
对于连续段\([l,r]\)和\([a,b]\),设\(l\leq a\)
若\(r<a\),最后合并出来依旧还是\([l,r]\)和\([a,b]\)
若\(r\geq a\),考虑\([l,r]\)和\([a,b]\)的交的大小:
- 若为\(0\),显然成立
- 若为\(1\),这个的操作显然最后会形如:\(1...101...1\),也就三段的样子
- 若为\(>1\),你此时可以考虑把最靠左的那个\(2\)给先提出一个\(1\),后面再加入进来,这个就是归纳证明了
当然这种方向你最后看下来感觉得到的\([l,r]\)的数量会比较难蚌,但你发现问题主要是,你这里不好计算,就你在\(>1\)的时候,加入的那个\(1\)所处的连续段\([l,r]\),可能会存在扩展后和其他连续段合并的情况之类的
那么我们现在换个方面,不考虑维护连续段,而是维护段\(([l,r],x)\),表示\([l,r]\)中除了\(x\)都是\(1\),因为你发现这玩意好像在你手模的情况中,出现频率相当之高
那么现在考虑\(([l,r],x)\)和\(([a,b],u)\)(\(l\leq a\))的合并:
如果\(r<a\),显然最后得到的就是\(([l,r],x)\)和\(([a,b],u)\),不管
如果\(r\geq a\),还是考虑交的大小和归纳证明法:
- 交的大小为\(1\),这是个比较普通的情况,显然最后得到的是一个我们要求的区间
- 交的大小\(>1\),同上面一样,把第一个\(=2\)的弄一个\(1\)出来,把剩下的操作完了现在再加回去,显然归纳证明可得最后得到的就是要求的区间
那么现在显然我们只要维护好所有的\(([l,r],x)\)即可,且显然数量是\(O(N)\)的,求答案的时候二分一下,不过因为题目比较好心,输入的操作都是升序的,所以直接指针就行
现在考虑怎么快速求得最后合并出来的东西,显然不可能真的像证明一样一层层递归,不然寄完了,但考虑到,我们只要知道了\(r-l+1\)和\([l,r]-\{x\}\)的所有元素之和,就可以唯一确定\(([l,r],x)\)(虽然某种意义上不是特别唯一,但实际上对应的同一个东西(?)
就因为现在相当于知道了\(len\)和\(sum\),显然对于所有区间左端点\(l\),它对应长度为\(len\)的区间得到的\(sum\)的值的范围在\(sum_{[l+1,l+len-1]}\)和\(sum_{[l,l+len-1-1]}\)间,也即\(l\)和\(l-1\)的值的范围只在端点处交一下
loj2815 「eJOI2018」AB 串
显然同色连续段不会割开,然后大分讨一手,贪心即可
复杂度\(O(N)\)
所以我们的复杂度就是\(O(M+Q)\)的了
PKU Campus 2025 Game on Tree
首先考虑链,显然边数不被\(3\)整除的时候先手必胜
现在考虑对于那些\(deg\geq 3\)的点
发现一个性质,如果有一个叶子\(x\),挂在一个\(deg\geq 3\)的点上,即删除\(x\)不会产生新的叶子,那么必胜
然后可以由此归纳证明出,如果只有一个\(deg\geq 3\)的点,那么就是所有叶子距离该点的\(dis\)都是偶数的时候,先手必败
然后再推广,就是提出所有\(deg\geq 3\)的点的虚树,那些不在虚树上的链,如果有深度为奇数的,就是先手必胜,否则必败
CF1672H
显然会删极长的区间
考虑删除过后,如果两边剩余的一样,则不会合并,否则合并
那么对于\(s_i=s_{i+1}\)的,视作\(i\)和\(i+1\)间有一个隔板,颜色为\(s_i\)
每次可以删掉一个隔板或一对相邻且异色的隔板
则答案就是区间内隔板两种颜色的数量最大值+1
CF1290E
考虑从小到大的插入数,发现一个点\(i\)的子树大小就是,找到极长区间\([l_i,r_i]\),其中\(i\in[l_i,r_i]\),且\(\forall j\in[l_i,r_i],a_j\leq a_i\),这个\(r_i-l_i+1\)就是\(i\)的子树大小
然后考虑到操作大概就是,区间\(+1\)或区间取\(min/max\),那么吉司机线段树就行
然后有点卡空间啊,很邪恶,所以先算完\(r\)再算\(l\)
复杂度\(O(NlogN)\)
CF809D
显然经典trick记录\(f[i]\)表示目前以\(\leq i\)的数为结尾的最长上升子序列长度,然后具体的,可以维护\(f'[i]=f[i]-f[i-1]\),显然\(f'[i]=0/1\),然后每次末尾来一个\([l,r]\)的区间就是删掉其中一部分,插入一个点,再把其中一部分平移一位
显然平衡树维护即可,平衡树上每个节点是\(f'[i]=1\)的点,记录的值就是这个\(i\)
复杂度\(O(NlogN)\)
CF401E
特判一下\(d=0\)的情况,就是极长同值连续段
对于\(d\geq 1\)的,首先合法的区间内,所有数\(\%d\)同余,且不能有相同的数,那么对每个右端点\(r\),可以指针维护它可能合法的最小的\(l\)
然后剩下的,就是要求\(\frac{mx-mn}d+1-(r-l+1)\leq k\),化简得到\(mx-mn+d\times(l-k)\leq d\times r\),那么线段树上对每个\(l\)维护对应的\(mx-mn+d\times(l-k)\)即可
一般常用的写法要单调栈来维护修改的区间,但是实际上可以直接在线段树上修改,复杂度和单调栈的那个一样,都是单\(log\)的,码量和常数应该会小一些
复杂度\(O(NlogN)\)
CF1423G
经典\(trick\),显然区间内种类数,但是可以转换成求区间内没有哪些数
然后要算的话,就是提出某一种值的所有位置,然后相邻位置间的空白部分距离为\(len\),则贡献有\(max(0,len-k+1)\),然后维护这个就行
复杂度\(O(NlogN)\)
P5897 [IOI 2013] wombats
首先可以想到行与行间用线段树维护,内部就维护一个\(dis[1\sim m][1\sim m]\)
直接做的话,合并的复杂度是\(O(M^3)\)的,显然暴毙了
考虑优化一下,发现我们有决策单调性,即\(dis[i][j]\)的转移点\(\leq\)\(dis[i][j+1]\)的转移点,这个证明是可以考虑\(dis[i][j]\)的路径和\(dis[i][j+1]\)的路径,如果有交,则必然有至少俩,把\(dis[i][j+1]\)交的部分替换成\(dis[i][j]\)的显然不劣
然后现在可以做到\(O(M^2logM)\),然后考虑到对于\(dis[i][j]\)和\(dis[i-1][j]\)也有同样的单调性,所以\(p[i][j]\)可以在\(p[i-1][j]\)和\(p[i][j+1]\)间枚举,复杂度就是\(O(\sum_i\sum_j p[i][j+1]-p[i-1][j])\),化简得到是\(O(M^2)\)的复杂度
但是现在空间不太放的下,这里有个\(trick\),就是当线段树上对应区间长度\(\leq 16\)时,直接暴力的算,可以做到\(O((r-l+1)M^2)\)
总复杂度\(O(NM^2+500M^2logN)\)
LOJ6507
居然是,势能分析!
考虑线段树维护,考虑似乎能想到的最简便的修改操作是区间赋值/区间加,显然这里前者更优
对于&操作,对每个节点记录区间内所有值的并\(b\)和或\(h\),如果\(h\&x=x\),则不用管,否则如果\(b\&x=h\&x\),则可以区间赋值,否则似乎只能递归下去
对于|操作,如果\(b\&x=x\),不用操作,否则,如果\(h|x=b|x\),那么直接区间赋值,不然只能递归下去
考虑能不能分析一下复杂度,发现如果当前层要递归下去的话,如果设势能为当前区间内所有数在二进制下,有\(0\)有\(1\)的数位的数量,那么递归下去的时候势能必减小
那么复杂度\(O(N(logN+logV))\)
BZOJ2138
显然前面的确定后直接可以把对应的\(v\)改成能取到的最大的值,现在就是想知道对于操作\(i\),最大的\(\leq v_i\)的值,使得能有一个完全匹配的方案,现在考虑一个方案\(check\)是否合法
根据\(hall\)定理,显然就是操作的子集的\(v\)之和\(\leq\)这个子集对应可以取到的所有\(a\)之和
又发现,因为题目说操作区间是不存在包含关系的,即按\(l\)排序后,\(r\)也不降,那么实际上子集只需要取连续区间段即可,然后它对应的能取到的\(a\)也直接视作一个区间即可
最后化简出来会得到取的值要\(\leq\)一个值,这个值可以通过线段树维护\(hall\)定理的那些东西得到
复杂度\(O(NlogN)\)
CF1340F
显然判断区间是否合法,可以线段树维护,合并的时候要求两个子区间都必须合法且左侧后面剩下的一对左括号,和右侧前面剩下的一对右括号能匹配上,这个用哈希判
然后具体合并的时候用楼房重建的单侧递归线段树的\(trick\)来判
复杂度\(O(Nlog^2N)\)
UOJ191 【集训队互测2016】Unknown
首先题目能转换成维护凸包,现在考虑怎么维护
如果没有删除,且查询是整体查询,显然二进制分组即可
如果没有删除,此时经典trick用线段树维护二进制分组,即区间内满了才算凸包
现在有删除,主要问题就在于,可以反复删除加入一个点,然后每次凸包合并都能达到\(O(N)\)的复杂度
我们想要规避这种情况,可以考虑当前节点的凸包要重建当且仅当在它区间内的点发生过变化,且它同层的下一个节点满了
考虑这样,首先询问的复杂度显然还是遍历\(O(logN)\)个点,则询问的总复杂度是\(O(Nlog^2N)\)的
删除的复杂度即叶子到根的所有点打上一个标记,复杂度\(O(NlogN)\)
插入导致的重建的复杂度,发现对于一个长度为\(len\)的节点,它当前重建距离上一次重建至少隔了\(O(len)\)的,则可以把重建的复杂度均摊到每个中间的时刻上,每个时刻摊到\(O(1)\),又因为考虑每次操作能把复杂度均摊到该次操作上的点数是\(O(logN)\)(即叶子到根的路径中,每个点的同层的上一个点)的,即重建的总复杂度是\(O(NlogN)\)的
总复杂度\(O(Nlog^2N)\)
P11291 【MX-S6-T3】「KDOI-11」简单的字符串问题 2
考虑一个贪心的步骤,那么对于每个点\(i\)记录\(f_i\)表示最大的\(j\)满足\(T_{[i,j]}\)是合法的
然后这个\(f_i\)可以线性算,具体的可以对所有的\(s\)串的反串建广义SAM,然后标记出哪些串是前缀,然后\(T\)也反着在上面跑就可以了
显然要算区间\([l,r]\)的最小的\(k\),就是令\(x=l\),然后跳到\([x,f_x]\)中间\(f\)最大的点,直到当前的\(f_x\geq r\),跳的总点数都是最小的\(k\),贡献就是\(K-k+1\)
然后显然可以建树了,然后考虑对于\(i\)的询问,容斥成总的减去区间\(r<i\)和区间\(l>i\)的答案,这个就又可以转换成要快速求出\(l=i\)/\(r=i\)的答案
考虑求\(l=i\)的答案,显然把那个跳的树建出来过后,\(f_i\)可以根据\(f_{fa_i}\)来推出
对于\(r=i\)的答案要麻烦点,因为我们贪心主要是以左端点为基准来贪的,对于\(r=i\)的话,对于所有\(\leq i\)的点,现在是一些森林,显然基本都遵循对于\(l\)的\(k\),是\(fa_l\)的\(k\)加\(1\),不满足的就是\(f_l\geq i\)且\(f_{fa_l}\geq i\),前面那部分显然用\(dep\)之类的可以直接算,而前后两种的分类也是好做的,因为有\(fa_l\leq f_l\),所以你操作完\(i\)后,掏出所有\(f_l=i\)的\(l\),然后把它的信息给\(fa_l\)维护即可
复杂度\(O(N)\)
CF1975H
感觉最多紫吧,思路挺自然的
考虑到显然就是让你最小化最大后缀,而最大后缀一定是以串中最大字符为开头的,设当前最大字符为#
先把所有#提出来,然后显然剩下的非最大字符要放到某个#的后面,且还会发现,一定有一个#后面是不放东西的,这里直接把这个不放东西的弄出来,然后现在把所有非最大字符从小到大排序后,放到那些当前可能座位最大后缀开头的#的后面
这里具体的可能作为的就是"字典序”最大的,这里我们的“字典序”的计算要在每个串后面加个\(+\infty\)后得到
显然加完这一轮,就变成一个子问题的,每两侧至少会减少一半的数量,复杂度是\(O(NlogN)\)的
当然可以做到线性,直接把所有字符提出来,按字典序排序,然后把当前第一个放到后面第一个字典序最大的位置上,显然这样做复杂度是\(O(N)\)的,然后为了规避一些关于要有一个#空出来的要求,直接一开始加入一个\(-\infty\)字符即可,如果当前字典序最大的串里有了\(-\infty\),现在就是答案
复杂度\(O(N)\)
P11343 [KTSC 2023 R1] 出租车旅行
显然经过的点中,除了最后那个点,都满足\(b\)递减
那可以先算出\(f_u\)表示从\(1\)走到\(u\)且全程\(b\)递减的最小代价
\(f_u=\min_{b_v>b_u} f_v+a_v+b_v\times dis(u,v)\)
最终答案\(h_u=\min_v f_v+a_v+b_v\times dis(u,v)\)
显然这俩都可以点分治+维护凸包得到答案,这里直接维护凸包或者用李超线段树都行
复杂度\(O(Nlog^2N)\)
gym105949 B
首先第一遍,显然你可以每一位用不同的数相加,然后根据它的下一位是否进位,如果进位,可以确定\(0\)对应的值,否则可以确定\(2\)对应的值
然后第二次询问,此时让俩相同的数(且还没确定的)相加,从前往后,看当前是否向前进位来确定具体的值
复杂度\(O(N)\)
诶这个交互题,我怎么怎么放fflush都不对啊/fn
gym105949 D
显然合法当且仅当最长下降子序列的长度\(\leq 3\),一个合理的构造就是点\(i\)的颜色取以它为结尾的最长下降子序列长度\(\%3\)
考虑怎么计数,首先暴力的想法,直接就着算最长下降子序列没前途
考虑Dilworth引理,可知合法序列可以分成\(\leq 3\)个上升子序列
Dilworth引理:一个偏序集可以被划分成的最少链的数量,等于这个偏序集中最大的反链的大小
大概就是一堆元素,有个比较规则,可比较一堆的是链,不可比较的一堆是反链
当然不用这个奇里八怪的引理,显然你最长下降子序列长度\(\leq d\),用下面这个做法就一定能找到一个合法的数量\(\leq d\)的上升子序列划分方式
总之你现在先维护一个三元组,初始就是\((0,0,0)\),然后每次\(i=1\to n\),找到\(<a_i\)的最大的那一位,改成\(a_i\)
显然可以做到三元组三个数不升,且这样很好\(dp\)
这里因为要比\(q\)的字典序大,所以可以枚举\(lcp\),那么现在只需要能算出在后面的方案数即可
那么直接\(dp[a][b][c]\),表示大于三元组第一/二/三位的剩余的数的数量
转移简单
总复杂度\(O(V^2+T\sum N_i^2)\)
gym105949 L
先假设区间里三种数都有,分别数量是\(a\)、\(b\)、\(c\),那么权值实际上就是\(\frac{|a-b|+|b-c|+|a-c|}2\)
这个很好算
考虑每个部分分别算,现在以\(|a-b|\)为例
实际上要有\(|a-b|\),则区间必须同时包含有\(a\)和\(b\),这个可以通过枚举区间内第一个\(a\)的位置,得到左端点\(l\)的区间,然后再根据左端点到这个\(a\)间有没有\(b\),得到\(r\)的区间
这里显然可以得到合法点对的区间,大致形如可以知道\(([l_1,l_2],[r_1,r_2])\)合法,\(l_2\leq r_1\)
总之这里大概就是大分讨出,包含三个的,两个的,一个的
然后用扫描线解决即可
另外俩同理
看官方\(sol\)的做法大概是先算出所有\(\frac{|a-b|+|b-c|+|a-c|}2\),然后把不合法的删掉,这个大概就是,以\(a\)不存在为例,然后算所有不存在\(a\)的区间的\(|a-b|\)、\(|a-c|\)的和,其实可以发现就是区间的长度
这样直接容斥掉的话,还需要对恰好包含俩的区间再加一下它们的那个\(\Delta\)
然后这里可能把单个的又算了一遍,所以再把单个的删了
复杂度都是\(O(NlogN)\)
qoj8092
注意到,对于一个点\(x\),在其子树内的询问点\(y\)对它有一个\(dep_x\geq ?\)的限制,对于在其子树外的询问点\(y\)对它有一个\(dep_x\leq ?\)的限制
那么就是说,一个点\(x\)能不能去掉某一个限制使得它的\(dep_x\)满足其他的所有限制
显然可以先建虚树,然后边上的点压到一起,还可以和虚树上的点再压,然后虚树外的点是子树压一起
当然为了方便,可以强行把根加入到虚树中
现在显然点集的数量是\(O(K)\)的(每个点集内\(dep\)限制相同)
然后对每个点集看它分别去掉\(dep\leq ?\)和\(dep\geq ?\)的最严的限制后,合法的点的数量
所有点集的这个点数加起来就是答案
复杂度\(O(NlogN)\)
CF1268D
这种就是要大胆猜然后证啊
证明懒的写,手模一下很简单
首先这个是个竞赛图,你会发现,如果一张\(n\geq 4\)的强联通竞赛图,那么能直接删一个点使得剩下的\(n-1\)个点的竞赛图也是强联通的
那么可以推得,对于\(n\geq 4\)的强联通竞赛图,那么能直接翻转一个点使得新图依旧强联通
进一步的,手模一下可以发现,\(n>6\)的时候,至多翻一个点就可以得到强联通的图
然后现在对于\(n\leq 6\)的,直接枚举哪些点翻转了,对于\(n>6\)的,去枚举翻转的哪一个点,直接\(check\)是单次\(O(N^2)\),不太行
考虑对于一张任意的有向竞赛图,缩点后,最下面那个\(scc\)的大小为\(k\),则该\(scc\)里所有点的出度和为\(C_k^2\),且显然这些点的出度是所有点里最小的\(k\)个
那么我们的\(check\)条件就是,把所有出度从小到大排序,如果存在于一个\(k<n\),使得前\(k\)个出度和等于\(C_k^2\),那么整张图就不强联通
这个的充要性,就考虑如果不是充要的,那就是你一个强联通分成了两半,前半是\(a\),后半是\(b\),然后说存在这个分法使得\(a\)里的出度和为\(C_a^2\),这显然不合法,因为必定存在\(a\)中向\(b\)连的边,所以出度和一定\(>C_a^2\)
那么复杂度\(O(N^2logN)\)
附赠一些有的没的:
大小为\(k\)的强联通竞赛图一定存在大小为\(3\sim k\)的环
qoj4787 Entanglement
直接递归就能过,复杂度分析的话,考虑你递归的时候在看每一行选什么值,然后对于当前局面,发现你划分出的子局面的,值不确定的列,是不交的
那么总共就\(O(NM)\)个局面,你每个局面可以做到\(O(M)\)算
总复杂度\(O(NM^2)\)
qoj4790 Inheritance
首先二分这个\(DIFF\)值,下面简称为\(d\)
考虑儿子层的区间,设为\([x,x+d]\),孙子层的设为\([y,y+d]\),设第\(i\)个儿子下面有\(a_i\)个孙子,先把这个\(\{a_i\}\)从小到大排序了
那么要有以下条件:
然后这种题一般都很套路,大概就是你直接推出合法的\(x/y\)的区间,然后\(check\)即可
这里显考虑去掉\(x\),首先可以得到:
然后对于那个\(k\)的限制,考虑到随着\(x\)的增大,\([\sum_i\max(x,a_i\times y),\sum_i\min(x+d,a_i\times(y+d))]\)也在往右挪,这里显然可以猜测这些区间的并不会有空隙
证明就是要证\(1+\sum_i\min(a_i\times(y+d),x+d)\geq\sum_i\max(a_i\times y,x+1)\),显然成立,得证
那么我们只需要对于最小和最大的\(x\)求出对应的左右端点,就能得到总的区间的并,然后再\(check\) \(k\)是否在里面即可
现在再来考虑去掉\(y\),或者一般来说是找点\(y\)的合法的单调性然后二分,这里不太支持双\(log\),所以直接考虑区间
而进一步的,以\(k\geq\sum_i\max(a_i\times y,a_n\times y-d)\)为例,就是要\(\forall p\leq n\),\(k\geq p\times(a_n\times y-d)+\sum_{i>p} a_i\times y\)
而\(k\leq\sum_i\min(a_i\times(y+d),a_1\times(y+d)+d)]\)就是,\(\forall p\leq n\),\(k\leq \sum_{i\leq p} a_i\times(y+d)+(n-p)\times (a_1\times(y+d)+d)\)
那么显然二分\(k\)后就可以算出一个\(y\)的范围,然后就可以\(check\)了
最大答案就是找到一组合法的\(k\)、\(x\)、\(y\),然后每个\(i\)分讨最低限度的苹果,如果缺了再补点就行
复杂度\(O(Nlog V)\)
cf17_final_j
复习Boruvka 最小生成树
显然可以用并查集维护联通块,考虑怎么快速求出每个联通块往外连的最小的边
一开始想的点分治,tmd点分治做魔怔了有点
显然可以换根\(dp\)求出整棵树中,到点\(x\)代价最小的颜色和次小的颜色以及其代价
然后直接算就行了,复杂度\(O(NlogN+N\alpha(N))\)

悲报,这个六一老登不爆米
浙公网安备 33010602011771号