我能以全 CQ 最菜选手的身份夺得 NOI 铁牌吗
6.1
我还是个孩子,菜菜是正常的。
Boss Rush
tzl 拉的题目。
首先考虑建图,容易想到要与 \(d\) 取模,取模后围成一个环。
发现可以离散化出来 \(O(n)\) 个点,CD 可以看作一条穿在环中间的边,直接 \(f_i\to (f_i+w)\ \text{mod}\ d\)。发现要格挡所有就是要经过 \(n\) 条边恰好一次。
容易想到欧拉回路,欧拉回路的判断是容易的,但是仔细想想会发现只有确定了结束时间后建图才是确定的,合法性又是随时间单调的,所以在外层套一个二分即可。
建图时,首先忽略格挡边,此时所有环边的条数是确定的,格挡边就相当于将覆盖的那些环边的条数都减一,只要边数非负且连通就是合法的。
乒乓
我拉的题。
记得这东西是 Para 在 24 年讲给我的,当时想半天不会,后来突然会了怎么求三元环的最大数量,甚至出了一道题到 HT-Rainbow,今天被 lf 催发现没题了就想起来了。
首先求三元环的最大数量是容易的,就是最小化 \(\binom{n}{3}-\sum \binom{d_i}{2}\),其中 \(d_i\) 是出度。
容易发现是平均分配最优,因为 \(\binom{a}{2}+\binom{b}{2}-\binom{a+1}{2}-\binom{b-1}{2}=a-b+1\)。
反正 \(m\) 大于最大值肯定是无解的,我们猜测小于等于最大值的都有解。
问题相当于就是构造 \(d\) 序列。
我们发现最大值的序列是 \(\lfloor \frac{n-1}{2} \rfloor,\lfloor \frac{n-1}{2} \rfloor,\dots,\lfloor \frac{n}{2} \rfloor,\lfloor \frac{n}{2} \rfloor\)。
最小值的序列是 \(0,1,2,\dots,n-2,n-1\)。
容易发现出度序列的每个值越接近三元环个数越多。
考虑使用调整法,上面我们已经得出了 \(\binom{a}{2}+\binom{b}{2}-\binom{a+1}{2}-\binom{b-1}{2}=a-b+1\),所以如果 \(a=b\),那么变化值一定为 \(1\)。同样,如果我们尝试翻转图上两个出度相同的点之间的边就一定会将 \(x,x\),变为 \(x-1,x+1\),不管初始边的朝向。
直接从最大值开始调整是 \(O(n^3)\) 的,考虑找一个三元环个数最小的大于 \(m\) 的“最大三元环图接上一条链”,然后从这里开始就行。
实现时可以先直接在度数上面操作,最后在根据度数构造图就行。
6.2
T1 是神秘构造,但是只能注意力极度惊人或者打表。但是孩子打表不好好打,非要先想一个错的剪枝然后打一个错的表一辈子找不出来规律。
黄焖鸡
T2.link.
好题哦,但是我是小飞舞哦。
首先发现只取奇数位或者偶数为都是独立集,所以独立集最小就是 \(\frac{sum}{2}\)。
发现本质是一个 ddp,同时维护以不同位置为左端点的 \(f_{i,0},f_{i,1}\),这表示是否选择第 \(i\) 位时的“选-不选”的最大值。
转移是 \((\max(f_{i,0},f_{i,1})-x,f_{i,1}+x)\gets (f_{i,0},f_{i,1})\)。
严肃发现集合中的很多数的没用的,比如如果 \(f_{i,0}>0\) 那么下一步转移时 \([-x,x]\) 这个东西一定更容易 GG,而我们只关心会不会 GG,所以只保留 \(f_{i,0}\le 0\) 的,然后你又发现根据定义 \(f_{i,1}\ge 0\),然后你就发现转移就变成了 \((f_{i,1}-x,f_{i,1}+x)\gets (f_{i,0},f_{i,1})\),因为初始状态是 \((0,0)\) 所以有用的 \(f_{i,0}+f_{i,1}=0\),因为 \(f_{i,0}\ge -m\),所以可以直接 \(2^{m+1}\) 状压起来,转移是简单的,可能需要一点点小优化。
博弈论基础训练2(基础在哪儿?)
Pocky Game
先考虑只有两个的时候该怎么做,显然是一个一个取。
扩展到三个呢?发现是如果剩下两个是必败就直接给自己的取完,否则只取一个继续等待。
此时容易得到两个结论:
- 只可能取一个或者全部取完
- 当前所在位置的值越大越优
再结合这个只能从两端取的限制,不难(?)想到区间 dp。
令 \(f_{l,r}\) 表示确定了 \(l+1,\dots,r\) 后 \(a_l\) 至少是多少才能必胜。
如果 \(a_r < g_{l + 1,r}\),那么直接取完之后对手就处于必败态了,所以直接取完,\(f_{l,r}=1\)。
如果 \(a_r\ge g_{l+1,r}\) 显然不可能直接取完,所以只取一个先等着,需要等到 \(a_r< g_{l+1,r}\) 的时候也就是 \(a_r-g_{l+1,r} + 1\) 但这真的对吗?如果中途 \(a_l < f_{l,r-1}\) 了那 Second 直接取完右边的你不就炸了,所以 \(f_{l,r}\) 还要加上一个 \(f_{l,r-1}\),也就是 \(f_{l,r-1}+a_r-g_{l+1,r} + 1\)。\(g_{l,r}\) 的转移是同理的,总时间复杂度 \(O(n^2)\)。
6.3
不对啊不对啊,怎么六月份才第三天就开摆了呀。
MIPT: Connecting People
首先答案显然可以看作 \(\sum\limits _u sz_u(n-sz_u)\),此时就只需要一个树形 dp 就可以求了。
令 \(f_{i, l, r}\) 表示以 \(i\) 这个点为根,子树是 \([l,r]\) 的所有楼的贡献,这里的 \(i\) 是对所有楼的每一层编号后的结果。
画图可以发现 \(f\) 可以拆成两个部分,如果 \(fa_i\) 在 \(i\) 的右侧,那么 \(i\) 往上的边就不可能连接 \(i\) 右边的子树,因为这样楼房会被 \((i,fa_i)\) 在这条路贯穿,而从 \(i\) 往下走的边也显然会构成一个连续的包含 \(i\) 的区间。
令 \(g_{i,l,r}\) 表示从 \(i\) 向下走,子树内部是 \([l,r]\) 内的所有点除去 \(i\) 上方的部分的贡献,\(h_{i,l,r}\) 表示子树内部是 \(i\) 向上的部分加上 \([l,r]\) 的贡献。
转移就不细说了,本体由于是三个 dp 树组并且边界处理很麻烦,所以用记忆化写或许会舒服很多,孩子一开始自己写发现写了最短解两倍长度之后还只写了一半,于是严肃学习。
下午是体锻,而且闹钟没闹醒睡过了……所以下午除了想了一会儿题干了 0 件事。
晚上是晚自习讨论,jmr 给了两道 hyw 题。神金,浪费 2.5h。
我去,这个训练状态去 NOI 真完蛋了吧。
[AGC026F] Manju Game
蚌埠住了,只会 \(O(n^3)\)。
首先发现就是先手确定一个起始点,后手选取一个方向然后两个人交替取,最后递归到子问题。
容易发现如果对于所有点黑白染色后,先手有一个答案的下界就是黑白点和中较大的那个,一直取边界就行。
你有发现如果取了一个点后有一边剩下偶数个数,那么后手就可以在下一轮直接变成先手,后手也会有这样一个理论下界,那么先手的答案就一定不会打与前面我们给出的理论下界,显然是不优的。
此时我们就解决了 \(n\) 为偶数时的问题,因为如果取中间就一定有一边会是偶数,所以干脆直接取边界取到黑白点中的最大值。
那么 \(n\) 为奇数是怎么办呢?显然先手要么取边上的黑点,要么取白点,此时后手会让你取完一边的全部白点,然后游戏继续进行。所以最后的情况一定是先手取了中间的一段黑(可能没有)加上两侧的所有白点。
后手肯定会尽可能往结果更劣的那一边取,这个东西不好直接算,考虑二分。
此时所有合法的黑点区间可以直接找出来。任何时候只要有一边先手搭不出来一个合法的区间那么先手就输了。可以发现先手能取到这个值的充要条件是先手可以找到一些白点使得这些白点将整段划分成的所有区间都是合法的。
6.4
早上模拟赛会 0 道题,被 lwz 和 pyt 292 创飞了,呜呜呜,好难过。
烧瓶
\(m\) 为奇数时重心一定只有一个,为偶数时一定是一条链。
先考虑奇数怎么做,只需要枚举重心,然后减去某个子树权重大于 \(\frac{m}{2}\) 的情况就行了,令 \(dp_{i}\) 表示在大小为 \(i\) 的子树内分配了 \(\frac{m}{2}\) 以上的墨水的方案数,首先 \(n^2\) 转移是容易的:
直接优化找不到出路,尝试递推转移,发现 \(dp_{i-1}\) 的所有方案在 \(dp_{i}\) 中都是合法的,所以只需要考虑增量就行了。
大致的意思是增量一定是恰好加上 \(i\) 的贡献后可以超过 \(\frac{m}{2}\)。
然后发现两个求和式可以根据组合意义化成一个组合数。
现在考虑如何处理偶数的情况,先算出上面那个贡献然后减去算重的情况。
可能比较容易想到直接大力点分治,我们考虑这个过程,就是对于 \(u\) 为中心时减去所有第一次走到的小于 \(u\) 的点在链上的贡献,然后还要加回两个这样的点在 \(u\) 两侧的贡献。
发现这个东西只跟点的相对大小有关,考虑从大到小枚举 \(u\),用并查集将所有 \(> u\) 的连通块连起来。对于所有与 \(u\) 相连的点 \(x\),如果 \(x<u\) 则记入贡献,否则除了 \(get(x) \to u\) 这条边的贡献其余所有 \(x\) 这个连通块的贡献都可以被记到 \(u\) 上。最后在容斥一下然后合并 \(u\) 和周围 \(>u\) 的点就行了。
修改
考虑如果修改是全局的该怎么做。
其实就是这个题:link.
有一个神奇的做法,就是对于每个 \(i\) 统计一下 \(p_i=\sum_j [j<i][a_j>a_i]\)。
每次全局操作时只要 \(p_i>0\) 那么位置都只会固定向前位移一单位。
而所有 \(p_i=0\) 的相对大小是不变的,所以如果二分出来一个前缀有多少个 \(p>0\) 的就知道前缀里 \(p=0\) 的是前几个了。
放到这道题就是直接大力询问分块,每个块都维护这样两个序列,不知道这种没营养的改编有什么意义。
字符串
我声称我是进步最快的选手,因为我什么都是弱项。
这种统计三元组肯定是要先固定一个枚举,容易想到固定 \(k\)。
你观察大样例可以发现答案是 \(O(L)\) 的,原因是考虑枚举 \(k\) 的每个前缀,找到这个前缀最长的在字符串集合里面的后缀,同理找到次长后缀,然后其余更短的后缀就一定不可能作为 \(i\) 或 \(j\),然后可能的 \(i,j\) 就直接 \(O(len)\) 个。由于对于 \(i\) 来说,\(j\) 必须是唯一的,所以考虑对 \(i\) 计数。
此时的充要条件就是 \(i\) 只会被其他区间中的一个覆盖,考虑将前缀的末尾从右往左扫描线,开个 set 维护所有左端点就行了,此时就可以找到有多少个最长或次长后缀覆盖了这个区间。但是可能有一些不合法区间本来被覆盖过但是由于被覆盖时不属于最长或次长而没被统计到。
这种情况只需要开个树状数组,对于每个 \(i\) 都将 \(i\) 的所有 fail 树上的祖先都标记为不合法,判断时必须要字数内没有被标记过的才可能合法。
Lexicopolis
发现 \(2\le n \le 50,1\le k \le 10^9\) 就容易想到矩阵乘法了。事实上字典序的相对大小也是可以用矩阵维护的,每次矩阵乘法之后再离散化一次就行了,有点类似倍增求 SA。
CF1761F2 Anti-median
很牛的一道题。
首先考虑长度为 \(3\) 的段,发现一定不是单增或者单减。所以如果将 \((i,p_i)\) 画在图上就一定是不停拐弯的样子,所以 \(1\) 和 \(n\) 一定是在奇偶性不同的位置,接下来假设 \(1\) 再奇数位。
那么如果排列合法那就一定是一个菱形的样子,其中 \(1\) 是下面的角 \(n\) 是上面的角,并且奇数位构成下半偶数位构成上半,然后基本就是对这个东西 dp,可以做到 \(O(n^2)\),细节较多。
然后就是比较难受的反射容斥优化了。
6.5
没干什么,基本空的时间都在补前两天缺的东西。
莫队之理
奇葩题,主要是 jsy 比较神经。
题目描述 70% 无用信息,还有一个神秘莫队参考资料。
其实就是直接贪心做就行了,本质就是期望 LIS 长度为 \(O(\sqrt n)\)。
QOJ12133 Stylemaxxing
\(1\le n \le 160\),很奇葩的复杂度,容易猜到网络流吧。
先考虑只有两种值的情况,发现就是个最小点覆盖,行列建二分图就行了。
正常转移的时候发现转移起点固定时边的存在性的单调的,所以可以压缩一维,然后就没了,这种东西好像用匈牙利会快很多,Dinic QOJ 上会 T,但模拟赛数据没事,所以就不管了。
最后的登山
容易发现只有 \(b_i=2\) 后面的位置的值是特殊的,其余值都是统一的,所以可以直接 \(O(n^2 2^m)\) 记忆化,然后就有 \(75\) 了。
赛时尝试疯狂分块,然后被最后一个点卡崩了,然后清楚 G 老师使用数据分治成功在赛后通过。正解好像是个什么神秘高斯消元,欸不想管了。
6.6
牢游一年前讲的连通性又来讲了一遍。
好像就广义串并联最有用,但是基本也是练熟点了,也没什么好记的。
还有个有意思的就是双极定向的构造,没错就是白鹭兰。
首先能够双极定向一定是若干点双构成的一条链,每个点双分开双极定向,最后串在一起就行了。
双极定向可以转换成定一个拓扑序,对于每个点双以 \(S\) 为根建 dfs 树,除了 \(S\to T\) 链上的点每个点 \(u\) 的 \(fa_u\) 和 \(low_u\) 向其连边。然后从 \(S\to T\) 枚举,直接 dfs 标号就行了。
前缀显然是连通的,后缀的话画一下图也能感觉到没问题,就是说如果一个点选了之后后缀从这里不连通了,那这个点在原图就是一个割点。
6.8
效率低成什么了,欸。
CF2118F Shifts and Swaps
我拉的题。
操作一的意思是操作二在环上操作。
如果没有操作一那么最终序列合法的充要条件是什么?
令所有值为 \(x\) 的数的下边组成的集合为 \(S_x\),则 \(\forall 1\le i < m\),进行若干次操作二后 \(S_i\) 和 \(S_{i+1}\) 两集合中的所有数的相对大小不变。
我们对于每个 \(i\) 从前面最近的一个值为 \(a_i-1\) 的点向其连边,没有则不连。
此时这个图是一个森林,合法当且仅当两个数组形成的森林完全同构,这里儿子的顺序以及根的顺序也不能变。
那么在环上该怎么做呢?
我们发现只要匹配好了 \(S_1\) 后问题就变得和链的情况一样了。
所以我们按一样的方法建森林,每次由环上向前走最近的一个值为 \(a_i-1\) 的点连向 \(i\),此时显然会形成 \(|S_1|\) 棵树,合法就当且仅当这两个数组的 \(|S_1|\) 棵树循环同构。
可以用哈希也可以用 kmp,实现是简单的。
好像还有一个从 \(1\sim m\) 依次找哪些位置可以匹配 \(b\) 中的第一个这个数,貌似要自然很多。
CF1483E Vabank
小学奥数说是。
容易想到一个 $3 \log $ 的直接二分做法。我又想出一个 \(\log_2+2\log_{3}+O(1)\),大致就是二分不优需要尽量往前偏一点,所以考虑三分,大概每两次可以分到 \(\frac{1}{3}\),中间还需要几次调整。但显然是过不了的。
换个思路,二分的时候我们会浪费很多次是因为我们没有做好平衡,有时需要花费额外操作次数来增加 \(s\) 使其合法就很麻烦。奇奇怪怪的乱搞无法通过,不妨尝试直接 dp。
但是不可能直接将剩余钱数直接记录下来,考虑记录当前大致还能删多少次(后面部分粘了一下 tzl 的课件)。
设 \(s\ge yL+(R-L)\)。
现在对于一次对 \(X\) 的询问:
- 失败了,考虑 \([L,X-1]\),此时 \(s'=yL-(R-L)-X\ge(y-1)L+(X-1-L)\)。
- 成功了,考虑 \([X+1,R]\),此时 \(s'=yL-(R-L)+X\),我们先假设它不小于 \((y+1)(X+1)+(R-X-1)\)。
即现在我们将问题变成了高楼扔鸡蛋的变体,不妨设 \(f_{x,y}\) 表示确定现在的 \(y\) 值还剩 \(x\) 次询问,最多可以找到答案的区间长度。
容易得到 \(f_{x,y}=f_{x-1,y+1}+1+f_{x-1,y-1}\),边界需要特殊考虑一下,但不是重点。
注意到我们之前做出了一个假设。
我们现在仔细考虑一下:\([(y+1)(X+1)+(R-X-1)]-[yL+(R-L)+X]\\\) 化简得:\((y-1)(X-L)-X\le(y-1)(X-L)\)。
也就是说我们每次成功的询问至多需要补充 \(Val=(y-1)(X-L)\) 的值到 \(s\) 中,显然所有的 \(X-L\) 的总和是不超过 \(Len\) 的。
现在继续意识流分析:我们观察之前 DP 出的询问策略,可以发现随着我们的询问,区间长度大致还是以指数衰减的,而每次询问最多就使 \(y\) 增加 \(1\)。\((y-1)\) 增大带来的影响会迅速地被 \(X-L\) 的减小削弱。故我们宣称总的 \(Val\) 是不超过 \(3Len\) 的,我们在每次要询问但发现目前的 \(s\) 小于询问的 \(X\) 时补充一次,一共不会补充超过 \(3\) 次。
啊,只能说这题神了好吧。
6.9
宿雾若水遥
树链剖分+颜色段均摊+历史版本和缝合怪。
缠忆君影梦相见
感觉好神的一道题。
一般图不好考虑我们可以尝试放到生成树上考虑。
突然又发现图是强连通当且仅当外向生成树和内向生成树都存在。
此时如果要不连通就一定需要删掉这 \(O(n)\) 条边中的一条。
那么如何快速求生成树呢?考虑 bfs,由于 \(n\le 50\),我们可以直接位运算优化。
此时就可以 \(O(n)\) 的复杂度找出两颗生成树,每次直接暴力枚举删哪个,发现只有 \(O(n^3)\) 个叶子状态,所以复杂度是 \(O(n^4 T)\)。
当然没有生成树的情况是好计算的。
晓月又经宵
不懂啊,就是根据询问区间和笛卡尔树上的区间的左右端点相对大小四种情况全部分开处理一遍。
6.10
优秀子序列
集合幂级数 exp 板子。
CF1773G Game of Questions
显然可能要将剩余哪些人做为状态。
令 \(dp_S\) 表示到达剩余 \(S\) 这些人的状态的概率。发现此时所有与 \(S\) 相交且不包含的所有题一定还没有被选择,其余的点此时再选择其实是不影响概率的。
如果没有能够影响 \(S\) 的题目了则说明处于结束状态,否则随机选择一个转移。
然后就可以进行一个子集枚举,预处理一下就可以做到 \(O(3^n)\)。
Virtual Self
FWT 具有线性性,所以题目求的相当于是从 \(n\) 个数中选择 \(m\) 然后将每个数单独做的 FWT 按位相乘后 IFWT。
考虑能否将所有情况合到一起进行 IFWT。
每个一个单独的数 FWT 出的结果都是若干 \(1/-1\),我们又知道选择了 \(m\) 个点,所以如果有 \(c\) 点到当前点的贡献为 \(-1\) 那么所有方案的 FWT 的值在这个下标的和就为:
现在问题就转换为了如何求 \(c\)。
我们发现对原数组做一遍 FWT 就可以得到每一位的 \((n-c)-c\)。
此时 \(c\) 已经得到了,但是这个组合式的复杂度还是过高了,考虑优化。
然后就可以直接卷了。
[集训队互测 2025] 少年汹涌
观察发现 \(w_i \le 62\),所以如果记录一下后 \(6\) 位前面每次的增量就是 \(0/1\) 了,就可以倍增了,令 \(dp_{i,j,k}\) 表示后 \(6\) 位状态为 \(i\),此时要跳后 \(6\) 位前面部分 \(2^j\) 步并且保证 \(j\) 后面的部分都是 \(0\),前面有额外的 \(k\) 个 \(1\)。
此时 \(n=1\) 已经解决了,主要就是考虑如何去掉算重的部分,容易想到在树上操作,只要确定了 dfn 序就可以很容易地算出重的部分,发现特殊性质 \(A\) 的 dfn 恰好就是大小。
那么为什么其他不满足按大小排呢?手玩一下发现有可能跳到层数相近之后会在 \(62\) 的差值内反复横跳。此时我的想法就是干脆直接一次性维护 \(62\) 个前面稳定部分相同的点,然后就可以 $2\log $ 搞定了。
还有两个方法,第一个是由树的方向延伸,可以发现我们是有快速求 lca 的方法的,所以考虑将虚树建出来,但同样的,我们难以确定 dfn 序,那我们能否就爱你一个不那么严谨的虚树呢?
这里有一个非常巧妙的解法,就是直接分治,每次将所有点都跳到分治到的这一个深度上,然后会合并成另一些点,这些点继续往上分治,剩下可合并在一起的点分子树往下分治。这样严谨虚树的每条边上最多只有 \(\log\) 个点,所以依然能做到 $2 \log $。
另一个方法是我们考虑给这棵树定一个 dfn 序,比如按连向儿子的边的大小从小到大走。然后我们是可以 $\log $ 求 lca 和比较两个点的 dfn 序相对大小的,所以直接排序就是 $2\log $,但是常数巨大。
Intranets
容易先想到一个 \(O(n^4)\) 的 dp,从大到小填边,同时维护一下现在的孤立点数和连通块数。
然后你就发现这样是无比浪费的,因为至多只有 \(O(n)\) 条边是有用的,考虑直接维护 \(dp_{i,j}\) 表示已经从大到小连了 \(i\) 条边,还有 \(j\) 个孤立点的概率。欸,又是概率,一些不会改变当前状态的转移是不影响概率的。
转移是分为连两个独立点和一个孤立点。我们发现连接两个孤立点的边的数量就是连通块的数量,因为要求了恰好 \(k\) 条,那么我们是否能找到一个较为容易的钦定计算方法从而使用二项式反演解决这个问题呢?
考虑钦定了 \(m\) 条连接两个孤立点的边,由于编号是不重要的,我们可以直接令从大到小就是 \((1,2),(3,4),\dots,(2m-1,2m)\),所有连接在这 \(2m\) 个点上的边一定要小于其连接的那个最小的钦定边。此时的偏序关系就形成了一棵树,而且每个子树内的点数是确定的,容易算出拓扑序合法的概率。
那么这道题就用 \(O(n)\) 复杂度解决了。
6.11
挑战
简单题。
回文计数
神经题。
发现贡献只跟 border 组成的集合有关,如果确定了这个集合是容易 dp 的,大致就是如果这个子串长度为 \(m\),令 \(dp_i\) 表示这个子串第一次出现的位置的结尾为 \(i\) 的方案数,直接用 \(k^{i-m}\) 减去出现在前面的方案数就行了。
那么如何找到所有这种集合呢?直接暴搜就可以了,没错,所以这是神经题。
枚举时可以使用并查集维护,如果这个 border 必定存在那么就记入,否则暴搜一下,然后更新并查集。用 uint128 记录状态。
如果一个状态枚举到最后并查集中有 \(c\) 个连通块那么方案数就是 \(k^c\)。
全部枚举出来之后还需要容斥一下,如果 \(i\) 被 \(j\) 包含则 \(s_j\) 需要减去 \(j\)。
有几个优化,根据转移长度大于 \(2m-n\) 的 border 时一定不会用到的,所以不用管。如果容斥后 \(s_i=0\) 那么就可以直接不管 \(i\) 这个状态。这样之后最大状态数只有几千,就,很离谱。
构造排列
也是神经题。
首先考虑将 \(a\) 转成 \(1,2,\dots,n\),此时算出 \(b\) 的逆序对数 \(S\),那么这 \(S\) 个数对要么对 \(a\) 贡献一个逆序对,要么给 \(b\) 一个,其余的对 \(a,b\) 都是等价的。
此时你就找到了一个必要条件,首先 \(|B-A|\le S\),并且 \(B-A\) 和 \(S\) 的奇偶性必须相同。然后 \(A,B\) 不能跳出可以取到的逆序对数的上下界。
这个其实就是有解的充要条件了。
证明是构造证明,大致方法就是临项交换,但是感觉很无聊。
\(O(n^2)\) 的解决方法每次直接枚举一个还没选的点放在最后一个位置,判定此时的后继状态是否合法,如果合法就做下去就行了。
发现 \(i\) 最小的,\(i\) 最大的,\(b_i\) 最小的,\(b_i\) 最大的中一定有一个是合法的,具体证明大致就是这四个点就是矩阵的四条边上的点,然后化成一个九宫格限制分讨。
3^N Minesweeper
三进制 FWT 板子,一样是按位往上推。
Flip Row or Col
水题,但是我看半天不知道怎么异或卷积,被 lwz 骂了呜呜。
Monotone OR
半在线高维前缀和板子。
实现大致是当一个点没有被分治区间覆盖过时他的前缀和就是当前确定的所有前缀加到上面后的结果。
如果叶子已经被覆盖过了为了防止给后面贡献的时候算重,前缀和的维度要停止在当前这个分治区间的层数。
6.13
题都挺不错的。
构造题
容易想到拆进制,发现二进制拆出来很浪费,因为每个数都会出现三次,其他整数进制都同理。所以我们不得不考虑小数进制(其实此时就有一点指向斐波那契了,更何况格路计数本就有一个类似斐波那契的转移)。
根据数据范围计算一下,由于 \(Y=960\),如果每个数出现两次,那么 \(1.6\) 进制是最优的。众所周知,斐波那契数列的底数是 \(\frac{\sqrt5+1}{2} \approx 1.6\),尝试使用斐波那契数来拆。
发现刚好够,然后就解决了。
匹配题
这种题必定要有一维是下标,有一维是状态提前或延后计算,这题是匹配所以考虑记录前面还有多少没被匹配的起点。
发现此时就已经 \(O(n^2)\),容易往延后计算的这些点颜色都相同的角度思考,如果现在有若干个颜色为 \(x\) 的起点。如果现在填一个 \(x\),只能作为左端点,那么如果填一个非 \(x\) 呢?发现如果这个点要作为新的左端点那么只有可能是后面某个单种颜色大量出现导致 \(x\) 点不够用,此时后面一大段必须是都以同种颜色为终点,否则必然是不优的。
仔细观察一下,我们就可以得到了一个结论:要么是一段相同颜色起点匹配任意颜色终点,要么是一段相同颜色终点匹配任意颜色起点。
这个性质非常优美啊,因为将序列反转后是等效的,并且这两种情况可以分开进行 dp 并且都比较好转移,那么这道题就做完了。
常数有点大。
作业题
这集神了。
\(n^2\) 是直接贪心,\(B\) 性质可以直接将包含关系的树建出来。
考虑一下 \(A\) 性质,此时对于每个点,参与的人一定是一个区间。匹配问题容易想到 Hall 定理,此时只需要求:
又因为所有区间都经过 \(x\) 这个中点,所有对于任意人的集合对应的作业的集合一定是一个完整的区间,所以取的人的集合也一定是一个区间。
题目就基本变成了一个求区间最大子段和,前缀和加线段树一下就行了。
关于正解,容易想到扫描线,观察每次移动 \(x\) 会发生什么变化。
如果一开始 \(x\) 在最右侧,那么每次往左移都会有一些区间加入,一些删除,那么还有什么变化呢?
因为有确定的终点,不难往前后缀的方向上考虑,令 \(i\) 这个人有 \(lc_i\) 个分配到了 \(\le x\) 的位置,有 \(rc_i=c_i-lc_i\) 分到了 \(>x\) 的位置。
一开始所有人选择的都是 \(\le x\) 的作业,每次 \(x\) 变小之后某些选择方案一定会从 \(lc\) 转移一部分到 \(rc\)。我们暂时先不管复杂度,考虑一下这个该如何维护。
类似 \(A\) 的贪心思路,以前缀为例,我们每次一定是选择 \(a\) 的一段前缀 \(1\sim p\),此时由于所有区间都包含了 \(x\),所以所有 \(l_i \le p\) 的区间都属于 \(N(S)\)。
相当于就是求:
也就是:
那么每次一定是找到右端点最靠右的一个可以取到最小值的前缀,否则如果转移的区间包含了一个最小值那么最小值一定会变小你移动的个数,显然是不优的。
然后随便维护一下这个位置到 \(x-1\) 中的所有左端点对应的最靠右的右端点,然后移动这个区间。原因是显然移到右端点越靠右越有助于右侧的最大匹配变大。
那么这个奇葩做法真的能过吗?
考虑分析复杂度,每次将 \(lc\) 往 \(rc\) 移一定会右两种结果,一种是 \(lc\) 被取空了,这部分的复杂度均摊下来显然没问题,另一种是最靠右的最小前缀的右端点严格向右移动了。
可是向右移动的部分有可能在增减区间的时候被影响操作次数,考虑势能分析。
我们定义势能为线段树上左儿子最小值严格小于右儿子的最小值的节点个数,这里的值维护的 Hall 定理。
那么每次区间修改至多会影响 \(O(\log n)\) 个节点。
而每次没有清空 \(lc\) 的移动操作一定会将新最小位置和原最小位置的 lca 处的节点的势能减 \(1\),因此,至多会移动 \(O(n \log n)\) 次。
总时间复杂度 \(O(n \log ^2 n)\)。欸,复杂度分析这一块儿。
6.15
那么我早上在干什么呢?问就是在补窟窿但是懒得写代码和总结。
Contention
我拉的题,拉简单题就是舒服你我他~
正向做没结果,后效性难以消除,考虑倒推,显然最后一个区间的贡献和前面的区间的顺序是没有关系的。
令第 \(i\) 个位置当前被剩下的区间覆盖了 \(c_i\) 次,那么 \(\sum_{l\le i \le r} [c_i=1]\) 就是填在最后一位分配到的座位数了。
发现每次取最大的这样一个区间是最优的,因为取完之后其余区间的价值之有可能增加或者不变。
维护是容易的,每次一旦有一个位置变成 \(1\) 了直接找到对应的那个区间,外面用个优先队列里面用个线段树就行了。
Nim Shortcuts
喜闻乐见的 Ad-hoc。
手玩容易发现如果 \(n=0\) 那么只有 \(x=y\) 的一条直线是必败的。
如果有一个点 \((a,b)\) 那么当 \(a=b\) 时不会有影响,\(a < b\) 时相当于删掉了一行,剩下的从原点开始的 \(45\) 度射线必败,\(a > b\) 相当于删掉一列。
多个点直接二维数点一下被删了多少行多少列就行。
使用巧妙一点的维护方式就行啦。
6.16
感觉这场不错啊。
互质序列
dp of dp 板子,简单。
树的搜索
算是 ddp 板子。
首先容易想到差分,此时 \(\ge x\) 的点称为黑点,\(< x\) 的点称为白点。
问题转化为求所有全是黑点的路径的概率和。
\(f_u\) 表示 \(u\) 开始走的答案,发现如果终点在 \(x\) 这个儿子的子数内那么概率为 \(\frac{1}{cnt_u+tag_x}\),其中 \(tag_u\) 表示 \(u\) 为根的子树是否不是全黑的,\(cnt_u\) 为所有儿子的 \(tag\) 和。
大致组合意义是所有不是全黑的子树一定不能在 \(x\) 之前选,全黑的子树一定会出来所以不影响概率。
然后就可以直接 ddp 了,要求单 \(\log\) 所以算个全局平衡二叉树板子。
调了挺久的,总结出来就是多分函数,更新矩阵的时候直接从一些数组推过来轻儿子的贡献,不要直接改矩阵,尽可能多用全局的 \(lst\),毕竟全局平衡二叉树形态和原树不同,容易错漏一些地方。
卡牌游戏
\(n^2\) 是直接记录 \(dp_i\) 表示上个选的位置是 \(i\)。
题目中的式子意思就是最大的公倍数,在纯随机倍数的个数是 \(O(\log n)\) 的,所以可以直接将贡献转到 \(a_i\) 的倍数上。具体的,令 \(dp_i\) 表示上一个位置的 \(a\) 是 \(i\) 的因数的最大值,可以 \(O(n\log n)\)。
此时就容易想到根号分治了。
如果两个点有一个是 \(\le B\) 的,可以直接把小的那个点的值记下来,都 \(>B\) 的直接倍数转移就行。前后缀都做一遍得到 \(f\) 和 \(g\)。
关于合并,如果两数有一个是 \(\le B\) 的,那就可以直接枚举小于 \(B\) 的那个数 \(v\),然后求一下 \(\max f_i+w(a_i,v)\),同时由于最小值 \(\le B\) 可以直接预处理出两个数都 \(\le B\) 的 gcd,然后最多只需要操作一次。
如果全是 \(> B\) 的,考虑枚举倍数,考虑扫描线一下,发现每次都会将 \(O(\sqrt n)\) 个位置的 \(g\) 中删掉一个数 \(f\) 中加上一个数。所以相当于是有 \(O(n \sqrt n)\) 个区间取 \(\max\) 操作,这里有一个非常牛的做法,就是“逆 ST 表”,大概就是每次只需要改两个 ST 表上的点最后 \(O(n \log n)\) 处理一遍就行了。
有点卡常,其中一个优化是说发现 \(\le B\) 的点间隔 \(3\) 个以上不选一定是不优的,因为两个 \(\le B\) 的 \(w\) 一定 \(> \frac{S}{2}\)。
6.18
CF1750G Doping
好题啊。
容易想到一个 \(O(n^3)\) 的二项式反演做法,复杂度瓶颈在于要进行 \(n\) 次二项式反演,非常浪费。
发现 \(n\) 个二项式反演是贡献到同一个数组上的,只是会有初始固定的下标偏移,考虑如何一起转移。
考虑二项式反演的组合意义,\(f_i= \sum_{j=i}^n g_j\binom{j}{i}(-1)^{j-i}\)。
容易看出来就是 \((0,0)\) 走到 \((i,j-i)\)。可是这样终点太散了,我们希望固定 \(f_i\) 所代表的点以便统计答案。考虑变成 \((j,0)\) 向左或下走到 \((i,i)\) 的所有路径的权值和,向下走是 \(-1\),向右是 \(1\)。
此时如果初始就固定了 \(k\) 个就直接从 \((j,k)\) 开始走就行。
此时就优化到了 \(O(n^2)\)。
ARC138F KD Tree
子问题划分写脸上了,容易想到 dp,难点在于如何去重。
此时有两个思路,一个是找到一个合法序列的判定方法,但是这道题的子问题划分方式都找到了就一般没什么必要使用这个方法。二就是对一每个最终状态只保留一种操作过程,比如字典序最小之类。
这道题中我们考虑字典序最小的操作序列进行计数。
发现如果你乱定义字典序根本无法进行容斥,这里考虑一个较为自然的字典序定义方法:\(x_1<y_1<x_2<y_2<\dots<x_n<y_n\),此时所有字典序更小的操作都在当前操作左下方。
然后画一画图就可以惊喜地发现如果第一次可以选择字典序更小的操作,那么更小的操作对应的集合一定是当前集合的子集,然后直接转移就做完了,可以使用状压加记忆化实现。
6.19
Codeforces Round 1104, Div. 1 + Div. 2.
A. Destroying Towers
水题。
B. Annoying the Ghost
吓哭了,B 这个难度不对劲吧。
赛时猜测应该是从小到大每次匹配最近的一个合法的点,结果对了。
证明应该是很简单的。
C. Duck Surplus
水题。
D. Fullmetal Bitchemist
大致的技巧就是对于这种不停删一段数的问题,尝试对不同值赋权,使得进行任意次操作后总权值不变,并且这个不变量恰好是基本充要的。
对于这道题,将 \(0\) 赋权维 \(1\),\(1\) 赋权为 \(2\)。此时在对于 \(3\) 取模的情况下刚好符合题意,只需要特殊考虑整段都是 \(01\) 交替的就行了。
E. Permutation Commutation
小模拟题。
F. Paint the Array
首先考虑合法的充要条件是什么,就是 \(\forall i \in [1,n-1]\),\(c_i+1=c_{i+1}\) 或 \(c_i=m\) 或 \(c_{i+1}=1\),构造证明这是充要的。
然后直接 \(dp_i\) 维护最后一个保留 \(i\) 的最多保留数量。
赛时降智了,直接用线段树维护当前最后一个点作为某个颜色的答案,写成依托。
G. Send GCDs
rk40 的 pyt 表示这题很板,但没关系,因为板题我都没见过,所以是好题(确信
观察一下限制,相当于要用每 \(10\) 个数来表示 \(9\) 个答案,\(10^6\) 容易想到 \(20\) 位的二进制,也就是要用若干 \(18\) 个二进制位的表示。
额外的 \(150\) 个数容易想到质因数分解,取某个质数 \(10^6\) 以内最大的次幂就行了。
发现最小的 \(150\) 个质数完全可以凑出来 \(2^{18}\) 个数,而原序列每个数可以表示为 \(20\) 位的二进制数,所以直接先转成二进制,然后 \(18\) 个分一段再转回去交给 B 就行了。
6.20
16 岁啦!
早上是简单模拟赛,下午在摆摆摆,晚上补了下题,随便打了场 HT。
6.21
[IOI 2017] Toy Train
原题目相当于是求手否能走到一个可充电的点上。
并不方便直接做,因为对于这种有有向图博弈问题我们是希望能够找到一个可以通过边进行转移的判断条件。
考虑转换成路径上的每个点都有一种使得先手必然能够走到一个可充电的点上的方法。
发现这个东西实际上和原题是等价的,稍稍迭代维护一下就做完了。
6.22
CF2023E Tree of Life
直接贪心是容易的,但是会出现某些合并的时候最大值大于总和一半导致浪费的情况。在这道题里,剩余的路径数是不超过子树内最大度数的,所以考虑直接以度数最大的点为根,此时一定不会出现绝对众数。
Ace in the Hole
猪猪好题!
题目相当于是要构造一种方案使得 Ben 不能确定任何一个点一定不是 1。
考虑第一次选择,如果 Ben 选择了 \(i<n\) 这个位置,那么 \(a_i\) 必定为 \(i+1\),大致证明就是如果不为 \(i+1\) 就一定可以确定 \(a_n\) 不为 \(1\)。
那么如果 \(i=n\) 呢?我们先研究一下 Ben 取什么地方有可能获得最大值,发现一定不可能是 \(\le n-2\) 的位置,因为此时 \(a_n\) 就不能为 \(1\),依次类推,每次最大值一定只能在最后两个位置取到。
所以此时如果选择了最后一个位置,那么最后一个位置一定只能填剩下的数中最大的或次大的,不然前面更大的数一定是递增排的,Ben 就会直接确定 \(1\) 不能填这些位置。
由于求的是字典序最大的,所以肯定优先填次大值,那么什么情况下必须填最大值呢?就是前面有数的大小在最大值和次大值之间,此时分讨一下如果最后一位是次大值,那么目前最大值的前一位一定不能填 \(1\) 然后直接维护就行了。
6.23
舞会
场切,妙妙题,大概就是多观察一下就会了?
吃鱼
首先需要观察到如果令 \(h_x\) 为 \(x\) 的二进制下最高位,那么 \(h_y<h_x\) 一定是全部取上最优,此时答案最多加一,因为最多取一个 \(h_y=h_x\)。
合法的充要条件是取了之后剩下的 \(h_y<h_x\) 依然可以取,算下来发现只有 \(\log V\) 个限制,直接在 Trie 树上求个交,再全部并起来就知道那些是合法的了。
轮子
循环移位后相同考虑 Polya 定理。
令 \(f(n)\) 表示环有长度为 \(n\) 的循环节时的方案数。
那么答案就是 \(\sum\limits _{i=1}^{n} f(\gcd(i,2n))=\sum\limits_{d|2n} f(d)\varphi(\frac{2n}{d})\)。
我们先钦定一个匹配方法,就是直接类似括号匹配一旦栈顶颜色与当前颜色相同就直接弹出。
对于 \(d\) 为偶数的情况,观察可以发现每个段内一定是要能够独立消除的,否则要么不合法,要么矛盾,对于 \(d\) 是技术的情况可以同理推断出段内经过一系列消除之后一定剩下一个长度为奇数的回文串。
那么一个合法的染色序列的方案数如何计算呢?
我们打一个 \(O(n^2)\) 的 dp 就可以发现从 \(dp_{i,0}\) 加数的贡献是 \(k\),其余加数的贡献是 \(k-1\),弹出的贡献是 \(1\)。
考虑直接枚举有多少次从 \(0\) 加数,如果有 \(m\) 次,那么写成括号序列就长成这样 \((S_1)(S_2)\dots (S_m)\)。
这是个经典问题,考虑双射成 \(S_1)S_2)\dots S_m)\) 进行计数,此时就可以格路计数反射容斥了。
那么奇数的情况怎么计数呢?发现如果空出来 \(j\) 个数,相当于有 \(j\) 个左括号没有匹配成功,那么序列可以写成:\((S_1)(S_2)\dots (S_m)(S_{m+1}(S_{m+2}(\dots(S_{m+j}\)。
枚举 \(j\) 是容易做到 \(O(n^2)\) 的,优化需要进行一个推式子的修行,这里就咕咕咕了。
6.24
这种神经模拟赛到底是从哪里找的?!
红魔馆警报器
Bostan_Mori 多项式题,出题人就是个。
快速求和
集幂题,但是水水水,但是卡常。
Zeryq
这个还挺有意思的。
首先看一下 \(\sum f_i\) 到底是个什么东西。
对于 \(f_i\) 答案显然为 \(i\) 左侧的大于 \(i\) 的段加上 \(i\) 右侧的小于 \(i\) 的段。
发现如果将小于 \(i\) 的视作 \(0\),\(i\) 视作 \(1\),大于 \(i\) 的视作 \(2\) 那求的就是相邻点的逆序对数。
容易发现,相邻点对于答案的总贡献是 \(\max(0, a_{i+1}-a_i-1)\)。
直接用连续段 dp 转移就行了。
Circular Tree Embedding
考虑先重标号一下,将第一个排列变成 \(1\sim n\)。
此时的限制相当于每个子树内的所有点的编号一定是连续的。
其余排列同理可得类似的限制。
此时一个区间可以作为子树当且仅当每个排列中这个区间的值都是连续的。
考虑先将其余排列都循环移位一下,将第一位变成 \(1\),此时将根固定为 \(1\),就只需要对 \(f_{2,n}\) 进行区间 dp 就行了,复杂度 \(n^3\)。
罕见的昆虫
要求最小出现次数,但是交互库只能返回最大,所以考虑是所有元素出现次数统一。
容易发现某个出现次数是否合法就是由最小值决定,考虑二分。
每次加入一个数后如果最大出现次数 \(\ge x\) 就弹出,不合法当且仅当总昆虫不是 \(typ \times x\)。
\(typ\) 可以直接在开始每种昆虫只加入一个求出,二分是每次都可以减去一般的判断量,总次数就为 \(3n\)。
每次将所有编号打乱后再判断,加一些小剪枝即可。
6.25
JOISC 2016 Sandwich
挺有意思的一道题,虽然搬题人有点大并。
求将两个块都取出这个显然有用,容易想到一个贪心就是取出一个之后立刻取出另一个,所以答案就是两者中较小值答案加一。
考虑暴力怎么做,发现由于钦定一个 \(x\) 是最后取的,所以如果是从斜边延伸出去那么那个块的两条横竖边必须都取掉才行,如果从横竖边出去那么斜边必须取掉。
直接做就是 \(O(n^2m^2)\) 了。
优化空间很大,容易发现的一点是每条行或列都是有一整个完整的连续依赖路径的,直接记忆化一下就可以 \(O(nm\min(n,m))\) 了。
6.30
Kanade 的水杯
哎呀哎呀,场切了。
发现所有数有两个来源,一个是向外移出后剩下的,一个是向前移动。
又发现往前移时如果有剩下的那么移到的位置目前的容量一定是 \(0\)。
直接线段树优化转移就行了。
Ena 的曲绘
很牛的题。
首先将 S 看成一个 01 序列,考虑如何判断是否合法。
发现如果有一个 \(k\) 满足 \(\forall x\in \Z,[xk,(x+1)k-1]\) 中的所有数都相同,就可以将每 \(k\) 个数缩在一起。
如果有一个 \(z\) 满足所有 \(1\) 后面都至少有 \(z\) 个 \(0\),那么就可以将 \(1000\dots00\) 缩成一个 \(1\)。
如果可以通过这两个操作缩成一个 \(1\) 那就是合法的。
惊喜地发现操作一可以看作取一个 \(n\) 的因数,操作二可以看作取一个 \(m\) 的因数。
而且为了避免算重,我们要求两个间隔着取。
那么如果将操作一操作 \(x\) 次的答案视作 \(A(x)\),操作二视作 \(B(x)\),那么答案就是:
此时 \(n,m\) 是等价的,问题变成了将若干小球放到 \(m\in [1, \sum a_i]\) 个盒子里的答案,同颜色的小球等价,第 \(i\) 个颜色有 \(a_i\) 个小球。
容易想到一个 \(O(n^2)\) 的二项式反演做法。
发现由于 \(\sum a_i\le 2\times 10^5\) 所以种类数只有根号级别,所以可以有空位的答案就可以 \(O(S\sqrt S)\) 求出。
二项式反演可以用 EGF 优化,总复杂度是 \(O(S \sqrt S)\)。
Soyo 的秘密
人类智慧题。
观察发现询问次数上界大概是 \(\log\)。
注意力惊人:如果 \(x\) 的二进制最后一位是 \(k\) 那么 \(d(x)\) 能被 \(k+1\) 整除,所以考虑从这里入手。
假设当前已经填了前 \(d\) 位,目前的值是 \(x\)。
那么第 \(d\) 位可以填 \(1\) 那么 \(ask(2^d-x)\) 必须被 \(k+1\) 整除。
同理,如果可以填 \(0\) 那么 \(ask(2^{d+1}-x)\) 必须能被 \(k+1\) 整除。
然后就是很神秘的操作:直接暴搜。
总之可以发现分出去的不合法的枝一定很少,价格记忆化和随机先取 \(0/1\) 就能过了。

浙公网安备 33010602011771号