AGC001 ~ 010
AGC001AGC001
AA
简单题,配对后是二者价值的较小值,相当于造一个合法括号序列然后所有左括号的价值和。最大化价值显然是将相邻两个括号配对。
BB
直接模拟光的轨迹。光从第二部开始每次都会变成形如从一个 60∘−120∘60∘−120∘ 的平行四边形的 120∘120∘ 角照入,直到从另一侧的 120∘120∘ 角射出。过程中会在两侧来回反射 ⌊ab⌋⌊ab⌋ 次,剩余子问题也是平行四边形,两边的长度为 b,amodbb,amodb,直接像欧几里得那样辗转相除就行,复杂度 O(logn)O(logn)。
CC
让 fi,jfi,j 表示 ii 子树内,深度不超过 jj 且直径 ≤k≤k 最少删几个点,转移形如 f′u,x=mini+j≤kfu,i+fv,jf′u,x=mini+j≤kfu,i+fv,j。
统计答案时需要枚举剩下的树里最高的点,删掉这棵子树的补树就行。
题解做法是直接枚举删后直径的中点,使得任何点到这个点距离都 ≤k2≤k2,直接在每个边上塞一个点可以避免枚举直径。
DD
相当于要把等号关系连成一个图,使得图连通。
总共至多有 ∑⌊ai2⌋+⌊n2⌋∑⌊ai2⌋+⌊n2⌋ 条边,nn 个点,所以当 ∑aimod2>2∑aimod2>2 时就无解。
在只考虑第一个串构成的等价关系中,一个奇数长回文对应着一个仅出现过一次的“会问中心”,其它等价类都出现过恰好两次,我们又要把这个图连通起来,所以一定是把这个度数为 11 的放在链的两端,其它穿成一条链。
前面想了很久没有想到构造方式,后来看了下 hint 就直接懂了。
考虑 m=1m=1 时的构造方式:
。
就错位一位然后就可以刚好把不同层连起来。
然后考虑如何把这些串穿起来,就只需要每个串能够接受一个“接头”再提供一个“接头”即可,如下图:
EE
选一个肉当作向上走一步,选一个菜向右走一步,等于求所有 (−A,−B)(−A,−B) 到 (A,B)(A,B) 的方案数和。
考虑值域不大,使用 meet-in-the-middle,从中间劈开,然后直接求左右走到中间这条线上某个高度的方案数,这个直接 O(A2)O(A2) dp 就行,然后查询左边走到 (0,x)(0,x) 和右边走到 (1,x)(1,x) 的方案数即可。
用题目语言说的话就是每放一个菜然后放一堆肉,处理出 f(i,j)f(i,j) 表示前 ii 个菜,用了还剩余 jj 个肉或是还需要借 −j−j 个肉的串的前半部分,后半部分的方案数。
聪明的题解直接使用了 dp 求出带求所有 (−A,−B)(−A,−B) 到 (A,B)(A,B) 的方案数和,相当于将所有起点的 dp 赋 1 后求所有终点的 dp 值的和。
F⋆F⋆
智慧。因为做过 Rearranging,对这个题略有思路但是没有找到正确的方法。
考虑这种原排列上的距离和值域上的差一很难受,不如转化成逆排列上相邻两个差。
令 Q=P−1Q=P−1 则能够交换 Qi,Qi+1Qi,Qi+1 的条件为 |Qi−Qi+1|≥k|Qi−Qi+1|≥k,然后变成了交换相邻两个,若干对 x,yx,y 的相对位置关系固定(不可互相跨过的),满足所有相对位置关系的显然可以交换得到。
即 Qi=x,Qj=y(i<j)Qi=x,Qj=y(i<j) 且 |x−y|<k|x−y|<k 那么 xx 在任意合法的 QQ 中都在 yy 的前面,即原排列上某个位置上的值要小于另一个位置的值。
拿回 PP 排列上就变成了如下问题:|i−j|<k|i−j|<k 且 Pi<PjPi<Pj 则最终也有 Pi<PjPi<Pj。
于是变成了如下问题:
求满足若干组 Pui<PviPui<Pvi 的字典序最小的排列。
考虑将关系的 DAG 建出来,我们要给每个点边上一个合法的拓扑序编号。
考虑优先级问题:
拓扑排序可以最小或最大化每个编号边号的点的字典序,但是我们要最小化的是每个点编到的编号的字典序。
为了想让小的点编号尽可能小,我们需要让大的编号编到尽可能大的点。
所以将原图的反图建出来然后直接倒着拓扑倒着编号即可。
现在问题是无法显式的建图,因为 u→vu→v 可能会有 O(n2)O(n2) 条,考虑主席树优化建图但是在本题的数据范围下会爆空间,所以考虑不显式地拓扑排序。直接每次找到那些度数为 00 的点并加入堆中找到字典序最小拓扑序。
一个点没有入度仅当它是 (i−k,i+k)(i−k,i+k) 的最大值,我们先将所有这些点加入优先队列中,考虑删除这个点即直接将这个位置赋值为无穷小。接下来可能会有至多两个点的度数变成 00,其一定是 (i−k,i)(i−k,i) 或 (i,i+k)(i,i+k) 的区间最值,检查度数是否为 00 后加入优先队列中即可。
复杂度 O(nlogn)O(nlogn)。
AGC002AGC002
AA
弱智题,数区间内负数个数即可。
BB
考虑模拟整个过程,维护每个盒子内是否可能有红球,从一个有红球的盒子里拿走一个球那么目标盒子就可能有红球。而起点盒子如果有且仅有一个球就没有红球了。
CC
考虑终状态,最后解开的那个结一定满足两侧那两段的绳长和 ≥L≥L,如果这个结都可以解开的话其它结直接从两边开始往中间解即可。
DD
可达的点数可以是 kk 等价于只经过 ≤w≤w 的边的可达点集的并的大小 ≥k≥k。
先二分 ww。
然后丢 kruskal 重构树板子,建出来重构树后两个点的可达的就是两棵子树或一棵子树,然后就直接向上倍增到不超过 ww 的最靠上的点。
并查集整体二分也可。
复杂度 O(nlog2n)O(nlog2n),题解疑似有单 log,明天看。
EE
考虑将糖堆排序看作一个直方图后,两种操作相当于从右边劈一刀劈掉一列和从下面劈一刀劈掉一行。
直到两条线的左上方没有直方图的部分,移动的人就输了。
考虑将这个过程视作“两条直线的交点处有一个棋子”,二人每次将棋子往左或网上移动一格,移动到图中这些点就输了。
这个可以 O(nA)O(nA) 地 dp 解决 f(i,j)=¬f(i,j+1)∨¬f(i+1,j)f(i,j)=¬f(i,j+1)∨¬f(i+1,j),但显然过不了,考虑从左到右扫描的过程中维护 dp 值,打个表会发现形如这样:。
10
2 2 3 3 6 6 7 7 10
2222222222222
1022222222222
0122222222222
1102222222222
1012222222222
0110102222222
1101012222222
1010110222222
0101101222222
1011011010222
每行内大于 ≥ai≥ai 的部分都是必胜状态的边界,在边界不发生变大的情况下是将整行的 dp 向左移动一格,并在末尾根据上一行末尾的状态添加 00 或 11。
如果在末尾变大的情况,然后在末尾添加上一段 0101 交替的序列,可能会有两个 11 出现相邻。
直接拿 deque 记录这些添加的 0101 段,然后模拟即可。
题解的做法非常智慧,观察到每一斜对角线的 dp 值都是相同的,可以直接判断 y=xy=x 和边界交界处的 dp 值,这个只需要算其离上边界和右边界的距离即可。
瓶颈在排序。
F⋆F⋆
令每种颜色第一个出现(非白球)为这种颜色的“色球”,其它为“剩余球”。
考虑基于什么去统计?我们要求每个色球前都有其对应的白球出现,即第 ii 个色球前面至少存在 ii 个白球。所以考虑基于白球和色球的位置关系去统计。
对于一个 白球-色球 序列,我们试图统计满足该要求的颜色序列个数,即我们要将每种颜色的剩余球放进序列中。
每种颜色的剩余球可以插入在其对应的色球后面,靠后的色球的可以插入的集合更小,所以考虑从后往前考虑每种色球的插入(如果从前往后考虑我们不知道前面有多少个色球插在了后面的集合里,而从后往前一定所有后面的球都插在了前面能够插的集合里)。
所以对于一个 白球-色球 序列的第 ii 个色球,其前面有 wiwi 个白球,我们要求 wi≥iwi≥i,那么我们要对后方长度为 (n−ci)+(n−i)×(k−1)(n−ci)+(n−i)×(k−1) 的球序列插入 k−2k−2 个剩余球(色球的位置确定在最前面的),方案数为 ((n−ci)+(n−i)×(k−1)+k−2k−2)((n−ci)+(n−i)×(k−1)+k−2k−2),所以整个序列的方案数即 ∏((n−ci)+(n−i)×(k−1)+k−2k−2)∏((n−ci)+(n−i)×(k−1)+k−2k−2)。
接下来就可以直接 dp 白球-色球序列了,考虑 fi,jfi,j 表示前 ii 个色球目前已经放了 jj 个白球对应的 ∏∏ 的系数和。
答案即 f(n,n)×n!f(n,n)×n!,因为我们区分每种颜色。
复杂度 O(n2)O(n2)。
应该学到的东西是 “基于某个特征要求,不重不漏地统计对应答案的个数”,和“从结果考虑,从过程 dp”的思想。
AGC003AGC003
AA
签到。
因为我们不在乎移动的长度,所以只要存在反方向的移动一定可以一次抵消所有该方向的移动,所以只需要判断 WE,SN 同时存在或不存在即可。
BB
直接猜到结论:答案即所有连通段的和除以二下取整,试图证明。
考虑对于每一个联通段直接从左到右贪心地拿一组,优先匹配上一个位置上剩下的,再将这个位置上的配对,显然每次配对完后只会剩下至多一个,取决于该联通段的奇偶性。
CC
感觉这个是超级典。
考虑 rev 相邻三个即交换 axax 和 ax+2ax+2
通过冒泡排序的方式可以将奇数和偶数下标的位置排好序,而无法交换奇偶下标。
所以一定需要把所有在偶下标的目标是奇下标,奇下标的目标是偶下标和且完成这些交换后一定可以通过交换三个分别对奇偶排序,所以找出在偶数下标终点的奇数下标数量即可。
DD
做出来啦。
一个暴力做法是直接对 aiai 分解质因数,然后将每个 cpiicpii 的 pipi 对 33 取模后,如果两个数 a,ba,b 的所有 pai+pbipai+pbi 都是 33 的倍数的话这两个数就不能同时选,即我们可以将数分成若干类,除了 ∀pi=0∀pi=0 的完全立方数本身最多选 11 个之外,其它类和与它乘起来是立方数的类是一一对应的,我们只需要在所有对应的类的组中选数多的那类即可。
困难是考虑无法对 aiai 分解质因数,O(n√Alog√A)O(n√Alog√A) 的复杂度是难以接受的,考虑这个数据范围比较像 O(A1/3)O(A1/3) 的复杂度,所以考虑对 AA 的范围进行分析。
取阈值 S=A1/3S=A1/3。
-
一个数的所有 ≤S≤S 的质因数我们是可以分解出来的,这部分复杂度 O(nSlogS)O(nSlogS)。
-
我们已经去除掉了所有 ≤S≤S 的质因数,接下来只剩下 >S>S 的质因数,该数剩下的部分一定可以被表示为至多两个这样的质数的乘积。
-
如果是两个数 p,q(p≠q)p,q(p≠q) 的乘积,那么这个数一定是可以被选的,因为如果要和它乘起来是立方数则需要带有因子 p2q2p2q2。
-
如果是个大于 S2S2 的质数 pp,那么一定可以被选中,因为如果想与这个数乘起来是立方数会带有因子 p2p2。
-
如果是个一个 (S,S2](S,S2] 的质数的平方 t2t2,那么我们将其放入因数分解中。
因为我们去除了所有 ≤S≤S 的因子,如果剩下的部分 B>S2B>S2,我们就只需要检查一下是否为某个 (S,S2](S,S2] 的质数的平方即可,如果是的话直接放入因数分解中,否则一定是两个质数的乘积或者大于 S2S2 的质数。直接选上。
如果 B≤S2B≤S2 的话因为我们已经枚举了所有 ≤S≤S 的因子,直接放入因数分解中即可。
时间复杂度 O(nSlogS+nw(A)logn)O(nSlogS+nw(A)logn)。
E⋆⋆E⋆⋆
一点不会。但是大好题!
考虑首先如果出现了一个长度 qiqi 然后后来又来了个更短 qjqj 的把它多出来的部分给砍掉了,那么 qiqi 屁用没有,所以先给操作上一遍单调栈,接下来 qq 单增。
令 Fl(x)Fl(x) 表示 A[1,l]A[1,l] 中 xx 出现的次数,FlFl 是一个向量。
首先因为串的周期性,比较容易得到下面这个结论:
如何查询 Fqimodqi−1Fqimodqi−1?
我们求出了所有 ii 之前的的 FqiFqi,所以可以直接通过拆成之前已经知道的 FqiFqi 来得到:
我们从后往前枚举 jj,FxFx 拆成 Fqj×⌊xqj⌋+FxmodqjFqj×⌊xqj⌋+Fxmodqj,一直递归到 f0f0 即可。
目前时间复杂度是 O(n3)O(n3) 的,怎么办?
正难则反。
其实我们本质上要求了一个 DAG 上所有点到某一个点的方案数,而上面的办法相当于求出了每个点到每个点的路径数,很没必要,因为我们只需要求其它点到这一个点的路径数,考虑在反图上求这个点到所有点的方案数。
像之前的做法我们求出了某个长度的串包含其它串的次数,现在我们改成求它被整串包含的次数。
我们从让 GlGl 表示长 ll 的前缀被原串包含的次数,然后直接按照前面的转移倒过来做(这里的所有 →→ 均指贡献到而非赋值):
然后对 Gqimodqi−1Gqimodqi−1 进行递归,像上面那样,对于 GxGx,倒着枚举 jj,GxGx 拆到 Gx×⌊xqj⌋→Gqj,Gxmodqj→GxGx×⌊xqj⌋→Gqj,Gxmodqj→Gx。
目前的时间复杂度是 O(n2)O(n2) 的,怎么办?
考虑有效的取模这个操作一定会让数的大小缩减至少一半,所以每次取模二分之前第一个 ≤x≤x 的 qiqi 取模,只需要取模 O(nlogw)O(nlogw) 次即可,复杂度 O(nlogwlogn)O(nlogwlogn)。
FF
看了题解。感觉没啥意思。
分情况,基于 原图形能否够上下、左右拼接联通。
如果同时能够上下左右拼接,那么无论按照任何铺满的方案原图都是四连通的。
如果同时不能拼接,那么考虑 k−1k−1 级别的分形的每个黑点都会被替换成一个原图,又因为它们互不连通所以答案就是黑点个数 Bk−1Bk−1。
如果只能横着拼接或者竖着拼接(不妨考虑只能横着)。
用样例举例子:
...|.#.|...
...|###|...
...|#.#|...
-----------
.#.|.#.|.#.
###|###|###
#.#|#.#|#.#
-----------
.#.|...|.#.
###|...|###
#.#|...|#.#
#
#-#-#
# #
我们最终要数有多少个连通块,因为两个原图形是无法竖着拼接的,所以用 k−1k−1 阶分形中的黑点数量减去拼接的次数,因为原图形是可以横着拼接的,所以拼接的次数就等于横着相邻的黑点对数。
考虑数相邻次数:
让原图中的黑点数量为 aa,原图中横着相邻的黑点对数为 bb,原图中能够最左列和最右列相邻的黑点数为 cc。
ii 阶分形中的黑点数量为 fifi,相邻的黑点对数是 gigi,左右拼接产生的相邻黑点对数是 hihi。
有如下转移:
其中 gigi 的转移,考虑相邻来源:要么是原本图形中的相邻翻倍得到,要么是新产生的相邻,i−1i−1 级上的每一个相邻都会产生原图左右相邻的次数次相邻。
hihi 则表示每次相邻靠边的位置都会被替换成原图中 cc 个相邻靠边的白格子。
转移重复冗余,直接上矩阵乘法,当然也可以推出通项后算等比数列。
周末有空研究下三维的情况。
AGC004AGC004
AA
送。 观察到不能平分仅当三维都是奇数,此时某个维会按照 ⌊x2⌋+⌈x2⌉⌊x2⌋+⌈x2⌉ 来划分,产生的不同的量就是一个平面即另外两维度乘积,选择最大的一维来划分即可。
BB
我测。我怎么搞了这么久久久。还想了一堆假做法,丢脸啊。
就是考虑最多的那个史莱姆需要变 xx 轮,那么我们至少需要加 xx 轮,其它史莱姆可以在过程中加入以达到让它变化 k≤xk≤x 轮变过去的效果。
然后就考虑枚举 xx,则一个史莱姆能够选择的来源可以是换上这个位置及其前 xx 个位置,直接查询区间最值即可,时间复杂度 O(n2)O(n2) 可以通过。
线性做法就是考虑每个史莱姆 ii 作为其后面某个位置 pp 的 [p−x,p][p−x,p] 中最小值的次数 cici,那么随着 xx 的变化,每个 cici 的变化都是一个至多三段的分段函数,斜率分别为 −1,0,1−1,0,1。
CC
简单题,考虑构造两个交为空的图形,然后在把原图中的紫点补上去,只需要保证补上去后连通即可,思路是使用一个连通的红图形并且使得它可以接触到所有紫点,蓝图形同理。
因为边界是空的所以有许多种不同的构造。
如这个梳子形:
#.#.#.
#.#.#.
#.#.#.
#.#.#.
######
和这种蛇形:
######
.....#
.###.#
.#.#.#
.#...#
.#####
DD
观察首先我们将树以 11 定位根,那么深度是连续的一段 [0,x][0,x],也就是说从点 11 开始经过 k,k−1,k−2,3,...,k−xk,k−1,k−2,3,...,k−x 个时刻都能够回到自己所以说 11 一定是自环。
接下来就是要将一些点连向 11,使得最终每个点的深度不超过 kk,直接贪心,若目前最深的点深度大于 kk 了,则它一定需要它的 [0,k−1][0,k−1] 级祖先中存在一个点连向 11,我们想同时解决尽可能多的点,又因为这是最深的点所以我们选择它的某个 [0,k−1][0,k−1] 级祖先 uu 一定是可以解决掉 uu 子树里所有点的,所以直接尽可能往上选即可。
EE
切铜牌题!不过可能是比较远古的套路。
令 Sx,SySx,Sy 为起点的横纵坐标。
使用相对移动大法。出口带着边界一起移动,在碰到出口前出边界的人寄寄了。
考虑一个时刻存活的人一定是若干时刻边界矩形的并,且四条边界只和矩形向上下左右移动最大位置相关,所以考虑记录 l,r,u,dl,r,u,d 表示矩形目前累计向左右上下四个方向已经累计移动的最大距离,那么这个矩阵中没有掉出去的只有子矩形 A[1+d,h−u],[1+r,w−l]A[1+d,h−u],[1+r,w−l] 这个区域内是有值的(即图中粉色圆圈所在的区域)。
并且此时出口可以在 A[Sx−u,Sx+d],[Sy−l,Sy+r]A[Sx−u,Sx+d],[Sy−l,Sy+r] 这个矩形内任意移动,可以收走这里面任意没被挤掉的人,但是注意到人可能在被挤下去之前就被收走了所以需要 dp,即每步移动加入可以收走的没有寄的人。
令 fl,r,u,dfl,r,u,d 表示四个方向移动量分别为 l,r,u,dl,r,u,d 时的最多可以收走出口可以移动的矩形内的多少人。
转移就枚举一个方向,例如出口向左移动一步到 fl+1,r,u,dfl+1,r,u,d,向左移动时如果这列还没有被从左边推掉,则加上出口能够活动的区间里面有值的这一部分,即 [Sx−u,Sx+d]∪[1+d,h−u][Sx−u,Sx+d]∪[1+d,h−u]。
时空复杂度都是 O(h2w2)O(h2w2) 的,空间有点卡,可以考虑滚动数组有点麻烦,一个更简单直白办法是观察到状态数其实只有 O(Sx(h−Sx)Sy(w−Sy))O(Sx(h−Sx)Sy(w−Sy)),又因为答案的值域是很小的所以直接上 vector<unsigned short>
即可,只需要 40M 左右。
FF
Ad-hoc。智慧。之前做过复习了一遍。
这个要求两个点两个点颜色相同就很难受,要求颜色的同时还会改变颜色,同黑同白操作之后分别对很多东西的影响还很复杂。
有解的一个必要条件是点的个数是偶数,进一步观察是将树二分图染色后奇偶点个数相同(这里称染的颜色为奇偶,题目中的颜色为“状态”),因为一次操作一定会同时改变一个奇点和一个偶点的状态,最终要改变所有点的状态。
然后就有了一个我也不知道是怎么想出来但是巨妙的转化:我们让每个点的状态异或上它的奇偶性,初始状态是所有偶点为白(奇点被异或成黑的了),最终状态是所有偶点为黑(奇点被异或成白的),操作是选择一对相邻的奇偶点,交换它们的黑白状态。
现在问题就是树上有一些 棋子(黑点),然后每次可以将棋子移动到一个相邻的,没有棋子的位置,求到达最终状态的最少步数,充分必要条件初始状态和目标状态的棋子个数相同。
这个还是蛮典的,直接考虑每条边两侧的棋子数量和目标数量,既可以求出这条边一侧要向另一侧移动多少个棋子,这个下界是可以达到的。
考虑基环树:
环为偶环的时候,图还是二分图,我们的棋子理论和染色方式仍然适用,还是移动棋子,先跑一棵生成树,让环边的移动次数为 00,然后考虑环边移动的次数对整个环上的影响,整个环的移动次数都可以增加某个值或减少某个值(整个环移动一次等于没有移动,所以可以整个移动一次或者整个往反方向移动一次以抵消掉一些原本的移动,如所有边按正方向移动一次可以通过整个环往反方向移动一次转化成环边往反方向移动一次),负值表示往反方向移动,决定这个值 αα,那么整个环上对应边的移动次数就是 |x−α||x−α|,所以就是所有 αα 取所有 |x||x| 中位数时 ∑|x−α|∑|x−α| 取最小值。
环为奇环的时候,图就不是二分图了,考虑当成树做然后单独处理这条环边的贡献:操作环边相当于同时改变两个颜色相同的奇点或者偶点,等价于凭空产生两个棋子或是吃掉两个棋子,这种时候棋子的数量是可以改变的,我们可以通过初始状态棋子个数和最终状态的个数确定出这条边的操作次数,提前在这个位置放若干个棋子,或者放若干个目标就行了(这条边可以在任意时刻吃掉/产生棋子,只要两边的位置都有/没有棋子就行)。
时间复杂度线性。
AGC005AGC005
AA
发现这是一个形如括号序列匹配的问题,即 ST 对应着 ()
,每次删除掉一组匹配的括号。所以直接求出所有不匹配的括号即可。
BB
从前往后扫 rr,单调栈维护 f(l)=mini∈[l,r]f(l)=mini∈[l,r] 的柱状图及其面积,弹出的时候维护面积即可。
CC
树上最远距离问题考虑直径,令 mx=maxai,mn=minaimx=maxai,mn=minai,则直径上一定形如 mx,mx−1,…mn(1 or 2),mn+1,mn+2,…mxmx,mx−1,…mn(1 or 2),mn+1,mn+2,…mx 这样。所以我们需要 [mn+1,mx][mn+1,mx] 的数都出现至少两次,且 mnmn 仅出现一次或两次。
其它 [mn+1,mx][mn+1,mx] 出现多于两次的可以挂在直径边上,故该条件充分必要。
DD
|ai−i|≠k|ai−i|≠k 太弱了,考虑容斥成 ai=i±kai=i±k,接下来问题就变成了对钦定若干 ai=i±kai=i±k 的排列的计数,观察这个钦定对 “排列”限制的影响,随便钦定发生冲突当且仅当 同时钦定了 ai=ai+2k=i+kai=ai+2k=i+k 或 ai+k=i=i+2kai+k=i=i+2k,我们可以发现这样的冲突是呈链式关系的,即我们对于一条冲突链“ai=i−k,ai=i+k,ai+2k=i+k,ai+2k=i+3k…ai=i−k,ai=i+k,ai+2k=i+k,ai+2k=i+3k…” 这样一条冲突链,不能钦定相邻两个冲突,其它都可以钦定,即一条链上选若干不相邻的方案数,需要求出若干条链上总共钦定了 xx 个相邻的方案数,直接对每条链做 dp 后背包,复杂度 O(n2)O(n2)。
使用 FFT 合并 Fs(x)=(s−i+1i)xiFs(x)=(s−i+1i)xi,时间复杂度 O(nlog2n)O(nlog2n)。
EE
普及组难度铜牌题,流汗。
-
首先手玩一些东西可以发现,如果出现一条 AA 中的边满足 BB 中两个端点的距离大于 22,且 AA 可以则 A 一定可以在这条边的两端戏耍 B,B 来不及跟过去,称之为长短结构。
-
游戏可以无限进行当且仅当出现了这种情况。分析:游戏无限进行仅当 A 可以在某些位置间游走,且 B 无法跟上 A,这种情况下一定出现了 disA(u,v)<disB(u,v)disA(u,v)<disB(u,v),若 u,vu,v 相邻就是上面那种情况(且 disB(u,v)disB(u,v) 一定至少是 33)。
-
若 u,vu,v 不相邻则可以找到 u,vu,v 在 AA 路径上相邻两个点的距离满足 disB(u,v)>2disB(u,v)>2,显然一定存在两个相邻的点没有连向同一点(首尾都不同)。
接下来若途中存在 A 可以到达的长短结构,则一定无限进行,所以 A 可以到达的两个点在 BB 上要么有边,要么可以被同一点到达,所以 A 此时的策略一定是走到一个点然后等死,不会因为 B 如何过来而改变,即先手永远不会逃离后手的子树中(长度为 22 的边仅能跨到兄弟,无法跨到子树外)。
处理处所有 A 能在 B 之前达到的点,求出这种点离 B 最远的距离就是答案。
FF
算 ∑Scov(S)∑Scov(S),考虑计算贡献 ∑p∑S[p∈cov(S)]∑p∑S[p∈cov(S)]。
枚举一个点 pp,则这个点被点集 SS 覆盖的 SS 计数等于 (nk)−∑v is a son of u(sizvk)(nk)−∑v is a son of u(sizvk),即不能全部在一棵子树里面。
考虑对于一个 kk,对于每个点都会贡献一个 (nk)(nk),减去的部分是对于无根树上的每一个大小为 ss 子树,都会减去 (sk)(sk),直接枚举 kk 和子树,复杂度 O(n2)O(n2)。
不关心具体是哪个子树,仅统计 cntxcntx 表示大小为 xx 的子树个数,那么对于一个确定的 kk 需要减去的情况之和等于 ∑(xk)cntx∑(xk)cntx,即求 ck=∑(ik)cnti=1k!∑(cnti×i!)×1(i−k)!ck=∑(ik)cnti=1k!∑(cnti×i!)×1(i−k)!,差卷积解决。
时间复杂度 O(nlogn)O(nlogn)。
好像独立做完了一场 AGC?
AGC006AGC006
AA
求出 SS 的后缀和 TT 的前缀的最大匹配量,该数据范围下直接暴力枚举,若需要线性直接哈希或者 sam。
BB
首先可以发现极值 11 和 2n−12n−1 肯定都无解的,猜测其它全部有解,观察到如果金字塔的某层出现了两个相邻的相同的数字那么他俩会一直上升到顶,所以考虑直接在中间构造出俩相同的数即可,具体这样搞:
…x+2,x−1,x,x+1,x−2……x+2,x−1,x,x+1,x−2…
x+2x+2 或 x−2x−2 不存在时另一个一定存在,因此下一层中间位置至少有俩相邻的 xx,可以一路到顶。
C⋆C⋆
让 ExEx 表示 xx 的位置期望,因为进行的对称操作只有加减法和乘常数,考虑期望的线性性,xx 关于 yy 对称后的位置的期望可以直接用 xx 和 yy 的位置的期望,那么 xx 进行一次跳跃后 ExEx 变为 (2Ex+1−Ex)+(2Ex−1−Ex)2=Ex+1+Ex−1−Ex(2Ex+1−Ex)+(2Ex−1−Ex)2=Ex+1+Ex−1−Ex,所以可以快速求出一轮。
然后呢?
妈的我不是做过方差吗。咋 还 不 会 交 换 差 分
观察上面这玩意交换后的 E′x+1−E′x=Ex−Ex−1,E′x−1−E′x=Ex−Ex+1E′x+1−E′x=Ex−Ex−1,E′x−1−E′x=Ex−Ex+1,设 dxdx 为 ExEx 的差分序列,则操作相当于交换 dxdx 和 dx+1dx+1。 接下来就是进行若干轮相同的交换,求最终序列。求出单轮交换的置换环,每个位置连到它后 kk 个位置的排列就是最终排列。
复杂度线性。
DD
之前听 Dreamoon 讲过关于中位数二分的技巧。
中位数,且只关心相对大小关系。 考虑解决较为特殊的 01 问题。
考虑 01 问题如果存在两个相邻的 0 或 1 肯定也会是向上一路直到边界的,并且如果这俩相邻的 0 或 1 的某侧是 01 相间的段则也会向这一侧扩展。
考虑离中间最近的相邻的两个相同的数的值,那么这个位置到中间的路上都是 01 相间的段,就会一直向左扩展从而占据中间两列。
e.g.
最后一行的 1 1 向中间扩展并占据了中间两列。
0 1 1 1 1
0 1 0 1 1 1 1
0 1 0 1 0 1 1 1 0
0 1 0 1 0 1 0 1 1 0 0
所以我们之需要求出离中间最近的相邻的两个相同的数的值即可。
我们解决了 01 问题,接下来考虑扩展到原问题,二分答案,检查答案是否大于 xx,此时只需要将所有 ai≥xai≥x 的 ii 位置上放 11,其他位置放 00,问题就被转化为 01 问题了。
把问题转化为 01 问题的好处是情况数变少了,只有 0 段 1 段和相间段三种,如果是第一个相同的说明之前全是相邻段。 这样减少情况的思维很重要。
时间复杂度 O(nlogn)O(nlogn)。
EE
首先因为旋转只会整列旋转,每列里面三个数永远在一列,且只会有 3x−2,3x−1,3x3x−2,3x−1,3x 和 3x,3x−1,3x−23x,3x−1,3x−2 两种顺序,处理掉不合法的,问题简化为如下:
有 nn 张牌,每张牌有正面 ii 和反面 −i−i,从状态 ai=iai=i 开始做若干次操作能否到达状态 ai=biai=bi,一次操作为:选择 1≤x≤n−21≤x≤n−2,交换 ax,ax+2ax,ax+2,并翻转 ax,ax+1,ax+2ax,ax+1,ax+2。
首先我们不考虑牌的正反面则问题就是奇偶独立的,可以交换奇数位置上相邻两个或偶数位置上相邻两个,只需要数和位置的奇偶性相同即可。
考虑正反面的话,我们不妨先把所有牌换到对应的位置上,那么这个时候每张牌只考虑同奇偶性的牌那么它现在的正反面只和 |pi−i||pi−i| 相关,但是另外一种奇偶性的牌在操作时会翻转若干次该奇偶性中的某些牌,我们可以决定翻转了哪些(这太复杂了),但知道翻转的次数是另外一个奇偶性逆序对数。
接下来试图通过一些操作仅对一些牌进行翻面而不改变位置,发现可以通过如下方式来同时翻转位置在奇序列或偶序列中相邻的两张牌:
考虑 i,i+2,i+4i,i+2,i+4 三张牌,我们交换位置 i,i+2i,i+2,再交换位置 i+2,i+4i+2,i+4 对于这些位置构成了长度为 33 置换环 i→i+2→i+4→ii→i+2→i+4→i,我们将这个置换进行 33 次,对这三张牌的位置和正反都没有改变,
能够改变相邻两张牌的正反这个性质非常强,从前往后依次处理,能够直接解决所有正反没有归位的牌的数量为偶数的情况。 如果正反没有归位的牌的数量为奇数,则一定无解,因为单独翻转一张内部的牌一定会影响到另外一侧的位置关系,因此我们只关心操作完后正反对不上的牌的数量的奇偶性,回收到上面,操作奇数序列对偶数序列的影响就是 奇数一个序列的逆序对数,偶对奇也相同,所以之需要求出排列的奇偶性即可。
时间复杂度 O(nlogn)O(nlogn),置换环判定排列奇偶性的话 O(n)O(n) 。
FF
又被我猜到了吧哈哈哈。
先转成图上问题,现在变成如果 a→b,b→ca→b,b→c 可以连 c→ac→a。
自环的传递性质自环的传递性质
如果有一个点出现自环,那么它所在的弱连通分量会被连成完全图,过程大概如下: 。
若点 bb 向点 aa 有边 b→ab→a,则 b→a,a→ab→a,a→a 则连接 a→ba→b。
若点 aa 向 bb 有边 a→ba→b,则 a→a,a→ba→a,a→b 连接 b→ab→a。
接下来有 a→b,b→aa→b,b→a 所以有 b→bb→b。
所以我们可以通过这样的方式连接这个点相邻的所有点并把自环传递过去,然后感觉似乎总是再通过任意的 a→b,b→ca→b,b→c 补上剩下的边(证明在后面)。
观察:不含自环连通块的形态观察:不含自环连通块的形态
如果一个连通块的最终状态不含有自环说明所有边 a→b,b→c,c→aa→b,b→c,c→a 满足 b≠c≠ab≠c≠a,我们说明我们可以对图进行 0,1,20,1,2 三染色使所有边属于 0→1,1→2,2→00→1,1→2,2→0 这三类。
猜测:答案总是可以连出所有不同颜色间的有向边猜测:答案总是可以连出所有不同颜色间的有向边
在对图进行三染色后(若存在这样的三染色显然唯一),猜测总是可以连出所有 0→1,1→2,2→00→1,1→2,2→0 的边。且不是 0→1,1→2,2→00→1,1→2,2→0 的边因为不会存在另外两条对应的边不会出现。
证明1:存在三染色且三种颜色都存在时,能够连出所有满足条件的边。
考虑一条存在三种颜色的链(方向不重要)一定可以构造出完全图来,试图归纳这一点:
三染色后我们不在乎边的方向(知道颜色就可以知道方向),接下来相当于如果一个三个点颜色不同的环连了两条边就可连第三条边。
若链 SS 之前只出现了两种颜色,不妨假设为 0,10,1,则新加入的颜色为 22,不妨假设该 22 目前连接了 11,11 更靠前的部分一定是 00,所以可以连接该边 2−02−0,然后可以通过这个 2−02−0 继续解决更短的问题,然后所有 0,10,1 都和 22 连起来了,可以连接所有 0−10−1。
若 SS 之前出现了三种颜色,不妨假设新加入的颜色为 22,则考虑之前大小为 n−1n−1 的满足条件的图,不妨假设加入这个 22 连接了一个 11,那么肯定可以通过这个 11 连接之前所有的 00,连接某个 00 后就可以通过这个 00 连接所有的 11。
接下来我们可以通过在图上取某两个期望连接的不同颜色的点和它们之间的弱连通链(不一定要求简单所以一定可以经过三种颜色),按照链的理论,我们将这条链上的所有点连成满足条件的图,这两个点自然一定可以连上边。
证明2:
严谨的证明有点无聊,给个有趣的。
因为不存在一种合法的三染色,所以我们可以任意选一个边的弱连通子集跑出来合法的三染色,然后使用 1 中的证明连上三部分之间的边,然后改变一些点的染色,选取另外一个满足条件的弱连通边集继续连边。一直这样就可以补上所有颜色不同的点之间该连的边,直到所有边都给连上了。
对每个若连通分量试图三染色即可,时间复杂度 O(n)O(n)。
较为一般的图上问题还是多从结果考虑啊,从过程考虑还是太麻烦了。
哎写了好多,感觉笔记应该直接丢结论和发现过程的。
AGC007AGC007
AA
将 \#\# 点按照 x+yx+y 排序,依次判断相邻两个位置是否是否满足后者在前者的右侧或下侧。
BB
考虑构造单调上升的序列 Ai=Ki+ai(ai<K),Bi=K(n−i)+bi(bi<K)Ai=Ki+ai(ai<K),Bi=K(n−i)+bi(bi<K),即可构造任意项的 Si=ai+bi+nKSi=ai+bi+nK,任意搭配 ai,biai,bi 序列满足条件即可。
CC
比较精妙的题,但是感觉出的有些刻意了?
因为球和坑是啥并不重要,我们只关心每段的距离,然后每次把一个球向左滚或者向右滚相当于消掉一个球和相邻的坑,我们现在考虑问题变成有个 2n+12n+1 个点的数轴,ii 与 i+1i+1 的距离是 didi,每次拿走两个点并向答案加上他俩的距离。
考虑期望的线性性,只需要关心每一步 didi 期望值即可,因为每一步拿走两个物品之后变为规模更小的子问题,考虑 didi 可能的变化:
第一种:d′id′i 没有发生变化,当且仅当拿走的两个位置都在 i+2i+2 及以后。
第二种:d′id′i 变化为 di+2di+2,当且仅当拿走的两个位置都在之前,ii 的位置发生改变。
第三种:d′id′i 变化为 di+di+1+di+2di+di+1+di+2
列出期望的定义可以得到 d′i=di+2d0+(4i+3)x2nd′i=di+2d0+(4i+3)x2n,发现这是一个长度为 n−1n−1 的等差数列,所以问题只要是等差数列,都可以归约到等差数列的子问题。
故我们可以通过记录等差数列的特征量 (n,d0,x)(n,d0,x) 来表示该数列并递推下一步新的等差数列,每一步一走的两个物品的期望距离就是这个等差数列的平均数。
时间复杂度 O(n)O(n)。
DD
不考虑糖果的话一定是直接从 00 走到 EE,考虑糖果就是在经过一个点后可能需要回来一趟,容易发现行走路径一定分为若干段 [l1,r1]…[lk,rk][l1,r1]…[lk,rk],走法为 0→r1→l1→r2→l2→…rk→lk→E0→r1→l1→r2→l2→…rk→lk→E,先走到段末,经过所有检查点一遍,然后回到起点,若 TT 秒已经到了,则直接回头,否则等待 TT 秒第一个检查点刷新后回头。
因为路程 0→E0→E 一定是要走一遍的,我们先不鸟他,直接考虑多走/多等待的时间,fifi 表示目前处理完 [1,i][1,i] 在 ii 的最少多走的距离,则有转移 fi=minj<ifj+max(2(xi−xj+1,T))fi=minj<ifj+max(2(xi−xj+1,T))。
使用双指针维护最小的 jj 使得 2(xi−xj+1)≤x2(xi−xj+1)≤x,minmin 取 2(xi−xj+1)2(xi−xj+1) 的部分记录前缀最大值,minmin 取 TT 的部分直接取 fjfj 即可,因为 ff 有单调性,复杂度线性。
EE
首先考虑题目要求每条边被经过两次,这说明了我们进入一个子树后一定会处理完子树内所有的叶子后离开该子树,否则子树上端那条边会进出至少两次,即经过至少四次。所以这说明了子树之间的独立性:某个子树在答案中一定是一个连续的区间,这引导我们从有根树信息自下向上拼接的角度考虑。
我们就可以将一个有根树抽象成三部分:从根进入 inin,内部最大值 maxmax,离开回到根 outout。内部的部分不会再发生改变,我们只关心它的最大值 maxmax,然后可以通过拼接两个子树离开-进入的信息来得到父亲的信息:(ina,outb,max(maxa,maxb,outa+inb))(ina,outb,max(maxa,maxb,outa+inb))。
因为这个过程是可以倒过来走的,于是我们就只需要设置 fa,bfa,b 表示进入左子树的 aa,从右子树的 bb 离开的最大值的最小值即可。
于是我们通过记录所有每个点所有 (in,out)(in,out) 对应的 maxmax 就有了一个 O(poly(n))O(poly(n)) 的做法(取决于你咋搞,反正难以低于 O(n2)O(n2))。
考虑优化:若要记录内部最大值是一件很浪费的事情,我们需要最小化最大的一次,又因为我们的过程涉及到了边的加和,故肯定得考虑二分答案转化为可行性问题,问题变为需要检测答案 DisDis 是否可行。
然后对于刚刚那个问题,我们便不再关心每个 (in,out)(in,out) 了,我们只关心每个 inin 值可以对应的 outout,且如果存在 in1≥in1,out1≥out2in1≥in1,out1≥out2,那么 (in1,out1)(in1,out1) 一定没用,于是我们可以通过维护一组单增的 inin 及其对应的一组单减的 outout 值来描述这个子树的信息。
考虑信息的拼接,即需要合并两组 A(in,out),B(in,out)A(in,out),B(in,out),合并的条件为若有 Aouti+Binj≤DisAouti+Binj≤Dis 则有 (Aini,Boutj)(Aini,Boutj),因为 AA 和 BB 都满足随着 inin 增,outout 减,所以可以按顺序枚举 AoutiAouti 双指针维护可行的 BinjBinj 即可。因为过程是可以倒过来走的,我们再把所有 (out,in)(out,in) 也加入,最终再排序/归并排序,去除掉没用的就可以得到父亲树内的 (in,out)(in,out) 序列。
直接这样做看上去复杂度是 O(∑sizi)=O(n2)O(∑sizi)=O(n2) 的,但是考虑因为我们记录的 (in,out)(in,out) 对中 (in,out)(in,out) 一者一定是左子树或右子树中的一个点深度,又因为我们保留的 inin 单增,outout 单减,所有这样的 (in,out)(in,out) 最多只有 2×lighti2×lighti 对,其中 lightilighti 表示 ii 的轻子树大小,所以复杂度是 O(∑lighti)=O(nlogn)O(∑lighti)=O(nlogn),加上外层二分,若使用归并时间复杂度 O(nlog2n)O(nlog2n),直接 sort
三只 loglog 也没啥问题。
这里是代码,实现使用了直接上传 vector
的做法,由于累计向父亲上传的大小之和仍然不大于轻子树大小,不会影响复杂度。
感觉这也不难啊为啥评了 *3900 .jpg
F⋆F⋆
S0S0 中每个字母在 TT 中呈现为一个区间 [li,ri][li,ri],首先对于所有终点对应非空区间的字符,其对应的 [li,ri][li,ri] 显然不交且从左到右依次排序,且 i≤lii≤li。
接下来找到每个字符对应的 [li,ri][li,ri],这个过程可以倒着枚举 TT 中的字符,找到之前最靠前的能够匹配上的字符。
考虑如何求出最少的轮数,我们将变化的过程画出表:
即一张表,每一步可以向右或向下,指定若干起点 ii 和终点 riri,所有路线不能相交的最少层数。
从后往前枚举起点,贪心地将路线向右紧贴上一条路线,直到终点对应的列向下走,显然这是不劣的。
使用队列维护目前路线所有的拐点,需要支持弹出队列末尾,在队列头部插入,以及整个队列 +1+1,可以通过记录一个 ΔΔ 实现,时间复杂度 O(n)O(n)。
AGC008AGC008
AA
枚举四种情况 A→B.A→−B,−A→−B,−A→BA→B.A→−B,−A→−B,−A→B,分别检查是否有 A′≤B′A′≤B′ ,更新答案。
BB
考虑每次涂黑或涂白的结果:一定存在一个长度至少为 KK 的连续黑段或白段。
考虑所有可能的结果:如果存在一个这样的段,则一定可以通过从两侧向中间依次决定每个不在该段里值的颜色,最后一笔将该段内的所有值涂成想要的颜色即可。
枚举一个长度 KK 的段,段内取 max(S,0)max(S,0) 表示可以黑可以白,段外取 ∑max(ai,0)∑max(ai,0),任意决定颜色。
用前缀和,复杂度线性。
CC
唐氏。最开始读错题了,出题人不要出多米诺&俄罗斯方块题了,真的很无聊。
考虑 "T" 和 "S" "Z" 这三种方块都会带来一个小的凸起,且这个小的突起是无法被补充上的(其它方块无法补充它们,而用这三种方块补充又会在另一侧产生新的突起),所以我们只考虑 "I","O","J"."L"。
显然 "O" 可以直接放在最下面或者最上面,一定可以放完,也没有与其它方块搭配的办法。
接下来是 "I","J","L",它们都可以和旋转 180∘180∘ 后和自己搭配产生一个 2x4 的长方形。也可以三种各消耗一个组成一个 2x6 的长方形(J 和 倒着的 L 放右边,I 放在 J 和 L 的框起来的空里)。
因为 "I","J","L" 都可以内部搭配,所以如果出现了两个或更多第二种 2x6 的长方形,一定可以拆开两个,换成三个 2x4 的长方形,所以这种长方形只会出现至多一个,我们考虑是否出现一个这种长方形,然后剩下的拿去尽可能多的 内部组成 2x4 长方形即可。
DD
先把 xixi 填上 ii,现在有若干要求 xixi 前面有恰好 i−1i−1 个 ii,从前往后填数,考虑限制之间的包含关系,肯定先满足尽可能靠前(紧张)的限制,在完成紧张的限制后再去完成靠后(宽松)的限制肯定是不劣的(如果靠后的放在前面完成一定可以交换到更后面),于是我们记录目前必须填的限制和目前可以自由填的数,若有必须填的数就填必须填的数,否则填自由填的,在某个 xixi 前必须填完所有必须填的 ii,在 xixi 后可以加入 n−in−i 个自由填的 ii。
直接记录一个数组,然后模拟,复杂度 O(n2)O(n2)。
EE
分析分析
i→aii→ai 构成内向基环树,配合暴力程序观察内向基环树常见的一些特殊情况:
灰色笔对应的是 i→aii→ai,黑色笔对应的是 i→pii→pi,我们相当于要构造一个黑色的排列(若干环)使得每一条灰色边的起点可以通过一条或两条黑色边到达终点。
ai=iai=i(全是自环):
可以任意选择若干对自环配对并连边,显然满足 i→j→ii→j→i,也可以选择直接 i→ii→i。
显然不可能出现三元环或更大的环因为不可能满足 i→j→ii→j→i。
ai=imodn+1ai=imodn+1(一个大的纯环):
首先显然 i→aii→ai 是一种满足条件的环。
考虑是否存在其它连边方式:存在一个 ii 满足 ppi=aippi=ai 的情况,因为环这种情况每个 aiai 只出现了一次,所以一定有所有 ii 都满足 ppi=aippi=ai(两步到达)。
当 nn 是大于 11 的奇数时,存在一种这样的连边:i→(i+⌈n2⌉)modni→(i+⌈n2⌉)modn,满足这种条件,如下图:
容易证明不存在其它连边方式。
两个大小相同的纯环:
假设环之间存在一条连边 i→ji→j,那么一定有 j→pij→pi,因此有 pi→pjpi→pj ……,可以根据第一条边确定整个环对应的连边方式。
环加一条链:
我们先来考虑这个链只有一个点 11 的情况:
对于这个链连着的点 uu 存在两个 ax=ay=uax=ay=u,也就说一定是 px=y,py=upx=y,py=u 或 py=x,px=upy=x,px=u(因为要求是排列)分别可以对应着下面这两种连接的方法。
对于更长的链也是类似的:在 uu 处选择上一步连接环上或链上 分别对应着提前 长度长度 个点开始交叉链和环,也可以选择提前 长度+1长度+1 个点开始交叉链和环。
基环树:
当基环树的形态不是“环+若干条链”的时候,即出现了并列的“分叉”情况,那么这个时候分叉的两个点 u,vu,v 之间必须得是串起来的关系,就无法让 x→u→vx→u→v 的 xx 满足 axax 为 pxpx 或 ppxppx 了。(因为题目的限制导致我们最多同时交叉着走两条链,要是交叉走三条就一定会出现 ppxppx 和 pxpx 都不等于 axax 的情况)
所以我们只考虑环+若干条链的这种形态的基环树,显然链之间是独立的,不可能互相连边,于是我们分别考虑每条链可能的情况即可,(从链进入/从环进入)可能的情况取决于这条链在环上离前面的链的长度。
非环的基环树是否可能还会有类似环的另一种连边方式?环的第二种连边方式需要满足所有 aiai 都为 ppippi(每一步都确定了),而这个时候就无法让多出来链上的点满足 pi=aipi=ai 了。(环的形态固定了,无法接入)
若要连接两个非环的基环树,因为环上部分的连接已经确定,且每步都满足 ppi=aippi=ai,因此无法使得有点连向非环的部分,所以非环的基环树一定只能内部连边。
结论结论
我们有着这样一些的连边方式:
-
对于一个任意的环,我们可以让 pi=aipi=ai。
-
对于一个任意长度为 n=2k+1(k∈N+)n=2k+1(k∈N+) 的环,我们可以让 pi=(ak+1)ipi=(ak+1)i。(上方有图)
-
对于两个长度都为 LL 的环,我们有 LL 种方式确定第一个环中某一个点连向的第二个环中的点,接下来每一步连接方式都确定了(为了连向上一步的 aiai),故有 LL 中连接两个环的方法。
-
对于一个非环的基环树,且形态为环加若干条链,我们可以决定每条长度为 LL 的链接入环的位置连向的是环还是链,分别需要对应连接环上前方 LL,L+1L+1 个点。
计数计数
因为基环树是独立的,我们先把所有基环树找出来并判断形态,然后求出每个点连出去的链长度,然后在环上转圈,找到每个链前面对应的空余长度,根据空余长度和链长度的大小关系分别对应着有 0,1,20,1,2 种连边方式的系数,对所有链的系数求乘积即可。
接下来就考虑若干环之间的连边,每种长度的环是独立的,对于所有环长为 LL 的环,枚举其连接两个环的数量 C(2C≤L)C(2C≤L),则将这些环配对的方案数为
这个组合数意义很好理解:选出 CC 个与 CC 个之间的对应关系,然后除以 2C2C 因为配对关系是无序的,左右等价。
每组环根据不同的错位有 LL 种连法,于是带有 LCLC 的系数。
特殊地,若环长 LL 为大于 11 的奇数,单个的环会有两种连法,再乘上 2L−2C2L−2C 即可。
对所有环长的答案求乘法原理,再乘上基环树的方案就是答案。
我咋天天场切 3500 啊?感觉这个结论还是蛮好猜的(?)
F⋆F⋆
考虑 SS 为所有点的特殊情况:
我们直接求每个点邻域的个数再求和,会算重一些点集,这种情况发生仅当这个邻域在某些方向“满了”,从而可以认为是向没满的方向移动一些并把这个点当作邻域的中心。
如下图中的黑色点集既可以表示为 vv 的 33 级邻域也可以表示为 uu 的 22 级邻域。
于是我们考虑在点集的“中心”,即邻域的 dd 最小时统计,容易发现对于所有不是全集的某个邻域,都存在唯一的一个点 uu 使得邻域的 dd 最小(尽可能不溢出),于是我们单独统计全集,接下来考虑枚举一个点并统计它作为中心的邻域。
令 fufu 表示 uu 在树上最远点的距离,gugu 表示次远点的距离,容易换根求出 fu,gufu,gu。
首先 dd 不能取 ≥fu≥fu 的值,因为我们现在只统计不是全集的集合。
接下来考虑 uu 是中心的条件:不能存在某个相邻的 vv 使得 vv 的 d−1d−1 级领域和 uu 的 dd 级领域相同,可以发现这种情况仅当除了 vv 方向的其它方向的子树内都是满的,显然 vv 只能在 fufu 所在子树的方向,且其它方向最远距离的点的距离都 ≤d−2≤d−2。(在 vv 处 d−1d−1 也能统计到)于是我们得到 dd 不能取 ≥gu+2≥gu+2 的值。
则 uu 可以选择的 dd 在 [0,min(fu−1,gu+1)][0,min(fu−1,gu+1)] 任意取,对所有值求和后加上全集即可。
接下来并不是所有点都可以选了,但我们仍然考虑在邻域邻域的中心 uu 处统计答案,即使这个中心并不能选择(我们统计的其它某个可以选的 vv 的 d1d1 级邻域但因为溢出而以 uu 为中心)。
若 uu 可以选择,则它作为中心的情况和上面相同。
若 uu 不能选择,则需要 uu 某个方向的一个可选择的 vv,填满它的子树并从 uu 向外延伸向其它方向。
我们把 uu 当作中心的话,需要这个 vv 所在的子树被填满(这样才能使中心向 uu 偏移,否则中心显然不能是 uu),并向外蔓延的距离至少要比这个子树的深度大,才可以把 uu 当作中心。
所以考虑 dd 能够取的最小值,即所有存在可以选择的点 的子树中,最深点深度的最小值,称为 huhu,通过换根求出即可,那么这个点可取的区间即 [hu,min(fu−1,gu+1)][hu,min(fu−1,gu+1)],对所有点求和再加上全集即可。
其实最开始解决这个问题时,我采用的办法是树定一个根,然后对于每个点集在可行的最靠上的 uu 的邻域统计。
在解决 SS 为所有点的情况时还可以用类似的办法解决(在钦定邻域中心不能上移的位置统计),但是无法拓展到 SS 不是全集的情况。
这启示我们在统计无根树问题的时候,最好还是采用更加「无根」的统计方式,比如“中心”、“重心”、“最近”之类的,而不是“公共祖先”、“最上方”之类的有根树方向。
--
AGC009AGC009
AA
经典地考虑从大到小确定每个范围,在大范围确定后改变小范围不会影响大范围已经完成的元素。
从后往前考虑每个位置,全都一直加到第一个 BiBi 的倍数即可。
BB
现在相当于确定了 11 号一路打上来变成了根,一些被 11 打败的人 uu 一路打上来构成的链按照某种顺序挂在 11 到向上的链上,然后又一些被 uu 打败的人 vv 一路打上来,按某种顺序挂在 uu 到 11 的链上 …… 然后需要最小化树的最大深度。
被 uu 打败的这些人打上来的树是若干个独立的子问题,我们先递归求解,得到它们最大深度的最小值 fvfv,然后接下来需要按照某种顺序排序 fifi 至一个数组 aiai 中,使得 fu=max{ai+i}fu=max{ai+i} 最小(挂在从上到下的第 ii 个位置会增加 ii 的深度),直接对 fifi 降序排序即可。
CC
直接 dp,可以令 fi,0/1,jfi,0/1,j 表示选择完 s1…sis1…si ,上一个是 A/BA/B 中的数,然后上一个在 B/AB/A 中的数是 SjSj 的方案数,复杂度 O(n2)O(n2),考虑这个状态的第二维有啥意义:目前在放 A/BA/B,加下来要到下一个 j+B/Aj+B/A 的数才可以转换正在放的数,去放另一个集合,于是改进 dp,直接转为记录 fi,0/1fi,0/1 表示目前在放 A/BA/B,且已经可以切换到另一个集合的方案数,转移有两种:1.在这个集合继续放一个 fi,0/1→fi+1,0/1fi,0/1→fi+1,0/1,当且仅当下一个和这个可同时被塞下 ;2.切换到另一个集合,那么下次可以切换的位置为之后第一个满足 sj+1sj+1 和 sisi 可以同时被塞进这个集合的位置。
统计答案时枚举最后一次切换即可。
观看题解发现其实可以直接对分给 A/BA/B 的极长的段的方案进行 dp,fi,0/1fi,0/1 s1…sis1…si,上一个是 A/BA/B 的段,然后直接可以找到转移过来的可行的区间,两个要求:这一段的全都能在 A/BA/B 塞下,上一段和下一段在 B/AB/A 中的差不会爆掉,这个要求对应的是一段区间,前缀和优化即可。其实很简单……
D⋆D⋆
非常妙,不是我能碰瓷的题。
分析:
考虑用一组标号 didi 描述 ii 在点分树上的高度,即 uninity,考虑怎样的一组 didi 是合法的?若满足任意 i≠j,di=dji≠j,di=dj,ii 到 jj 的路径上至少存在一个 dk>didk>di。一定可以被按照从 didi 大到小的构造出合法的点分树,且因为上条件所有路径都会被对应的最大 kk 分治到,这是充分必要的。
因此我们就是要找到一组合法的标号。
结论:
声称以下结论:对于一个根, 从下到上贪心地给每个点定不和下方冲突的尽可能小的标号即可找到最大标号的最小值。
实现:
从下到上贪心,对于每个子树维护 banubanu 表示 uu 子树内存在这些标号 vv,某个标号 vv 的点到 uu 路径不存在比 vv 大的值,考虑所有子树 banubanu 的交,显然 uu 的标号不能在这里面取,并且若两个不同的子树中存在 t∈banx,t∈banvt∈banx,t∈banv,du>tdu>t(否则两个子树中就会冲突)。
接下来我们选择最小的满足条件的 dudu 即可。
证明:
AT 题解使用了一个很妙的理解方式,取巨大 Base BB,定义 V(S)V(S) 为 ∑i∈SBi∑i∈SBi,那么我们每次需要找到一个 banubanu 使得 V(banu)>∑V(banv)V(banu)>∑V(banv)(这意味着某位出现两个数就要求要在更大位填数了,且只能填一个更高的位并把后面的推平为 00),并且我们希望从根节点输出的 V(banrt)V(banrt) 最小,因此每一步都选择最小的 V(banu)V(banu) 是对的。
其实用人话说就是若子树内多出了一个大标号,对上方的影响严格大于任意多的小标号。
优化:
因为这个集合的大小显然是 ≤O(logn)≤O(logn) 的,操作也全是推平若干位、交集、并集、集合最值,故压到一个 word 里来维护集合,若字长 w≥nw≥n,即可做到 O(nlognw)≈O(n)O(nlognw)≈O(n)。
总结:
当问题无从下手时,试图为每个点抽象出一个相对独立的信息及合法的充分必要条件,然后考虑按照某种顺序来考虑这个条件的成立,并不一定被局限于按照原问题的顺序考虑,这可能会导致信息难以记录。
EE
想了半天怎么对树的这个结构 dp…… 然后选择了看题解,可以看出我现在的状态多么糟糕。
首先显然这个合并结构等价于一棵 kk 叉树,令根节点深度为 00,在叶子处放数,每个 11 对应的权值是 k−depk−dep。
考虑 dp 树是一件很困难的事情,尤其是还要记录深度相关的信息。我们不妨来直接 dp 数,考虑哪些数可以被考虑出来。
令 d=(n+m−1)k−1d=(n+m−1)k−1。
我们考虑一个 kk 进制小数 x=0.c1c2…clenx=0.c1c2…clen 能够被表示出来的充要条件,经典地,我们试图先找一些必要条件并在稍后说明充分性:
首先得 xx 可以被 nn 个 k−pk−p 表达出来,但是因为我们有树形结构的限制,并不能造出任意数量的任意位,这还不够充分,树形结构下 kk 个叶子合起来到下一层的过程很像进位,于是我们考虑把所有 00 的地方都改成 11,最后一定会在根处的值为 11,因此我们需要离 11 差的部分能够被 00 表达出来,即 1−x1−x 可以被 mm 个 k−qk−q 表达出来,这个条件很强,已经是充分的了:因为 (∑k−qi)+(∑k−pi)=1(∑k−qi)+(∑k−pi)=1 ,我们总是可以从最低位的 k−ck−c 开始选择 kk 个并进位形成树形结构,若无法选出 kk 个说明这个和在小数的这位上不是 00,显然不能够使得和为 11。
将这些“ xx 可以被 nn 个 k−pk−p 表达出来”写出来:
- ∑ci≤n∑ci≤n :一个 11 最多提供 kk 进制小数下 11 的数位和,进位显然不会增加这个和。
- (n−∑ci)mod(k−1)=0(n−∑ci)mod(k−1)=0:可以通过任意多的进位来怎加 k−1k−1 个拆分出来的数。
同理我们需要,1−x1−x 可以被 mm 个 k−qk−q 表达出来
- ∑(k−1−ci)+1≤m∑(k−1−ci)+1≤m :即考虑 1−x1−x 的数位和,最后一位为 k−cik−ci,其它位为退位 k−1−cik−1−ci。
- m−(∑(k−1−ci)+1)mod(k−1)=0m−(∑(k−1−ci)+1)mod(k−1)=0:进位来怎加 k−1k−1 个拆分出来的数。
容易对 cici 进行 dp:fi,jfi,j 长度为 ii,,∑ci=j∑ci=j 的序列的个数。
时间复杂度 O(n2)O(n2)。
AGC010AGC010
AA
因为合并两个奇数或偶数都会产生偶数,所以最后一定会有一个偶数,当和是奇数时最终状态会剩一个奇数,和是偶数的时候一定可以。
BB
考虑环上差分 ci=ai−ai−1(a0=an)ci=ai−ai−1(a0=an),则一次题中操作进行的是对所有位置都 −1−1,再对起始位置 +n+n。
因此假设以 ii 为起始位置做了 mimi 次则有 c′i=ci+n×mi−∑mic′i=ci+n×mi−∑mi,最终我们为了让所有 cici 变成 00,每个 cici 和最大值 cmaxcmax 的差值只会在选择 ii 作为起点时发生改变,所以我们要求每个 cici 和最大值的差值都是 nn 的倍数,同时我们可以求出每个位置上操作的次数。
所有数在操作后都变成了同一个数 xx,若所有 xx 都为正整数且是 n(n+1)2n(n+1)2 的倍数,这样可以通过在每个起点做一遍以将所有数减去该值。
CC
即选择若干条叶子到叶子的路线,使得每个点恰好经过 aiai 次。
考虑从叶子节点开始处理,每个点要求经过其父亲 bibi 次,其中 bleaf=aleafbleaf=aleaf。
考虑一个节点 uu 有若干儿子,分别要求经过 bs1,bs2…bskbs1,bs2…bsk 次,令 ∑bsi∑bsi 为 SS,若 S=buS=bu 则所有路径都恰好是经过 SS 向外的,而 S=2buS=2bu 时恰好所有路径都是经过 uu,在 uu 子树内配对的,因此仅在 S∈[bu,2bu]S∈[bu,2bu] 时有解,并我们可以确定出在 uu 子树中配对的路径数 Pair=S−auPair=S−au,以及向外的路径数 bu=S−2Pairbu=S−2Pair,由于不能将同一个子树内的路径配对,考虑 bibi 最大的子树,若超过了一半则路径无法全部配完,最多配 S−maxbiS−maxbi 对,检查是否有 Pair≤S−maxbiPair≤S−maxbi,这个过程中我们确定了 bubu,继续上传,考虑上方的节点即可。
D⋆D⋆
呜呜呜没有智慧。
考虑如果出现一个 11 的时候,偶数的奇偶性就决定了是先手 win 还是后手 win,若有奇数个偶数,先手就赢了。
猜测有奇数个偶数时先手必胜,理由很简单,先手只需要使一个偶数减一,此时一定会存在至少两个奇数,后手无论操作什么仍然无法使得场上带有公因数 22,在除 gcdgcd 后不改变奇偶性,偶数个数仍然是奇数。
若有偶数个偶数,则先手必须要想方设法打破这个局面,使得操作后不出现奇数个偶数,若挑一个偶数 −1−1 后此时存在奇数,在除 gcdgcd 偶数个数是奇数,没救,所以只能挑一个奇数,而若此时有多余两个奇数或有 11 就 lose 了,若只有一个奇数就使这个奇数 −1−1,此时所有数都是偶数,除 gcdgcd 后递归子问题,把局面交给对手判断。
因为递归交给对手这种情况会使得所有数至少除以二,所以只会递归 logAlogA 次,时间复杂度 O(nlogA)O(nlogA)。
-
观察奇偶性在这种轮流操作的题目中还是很重要的。
-
对于某些博弈论题目,当有一个比较强结论可以判定某局面一定是必胜态时(充分条件),要判定必败不一定要找出必要条件,可以考虑其不是必胜的后继,然后递归解决这些可能的后继。
EE
之前听 dxm 学姐讲的题,很厉害,在经典套路的基础上加入了大量的脑子。
对于形如这样的问题:
有排列 pipi 和无向图 GG,可以执行若干次交换相邻两个数,当且仅当 GG 中有边 (pi,pi+1)(pi,pi+1),最大化字典序。
考虑 GG 的补图 aGaG,其中的边 (u,v)(u,v) 两侧的元素两两不能跨过,则有因此根据 u,vu,v 在 pp 中的位置对 (u,v)(u,v) 定向,则最终的 p′p′ 可以通过交换的得到的充分必要条件是 p′p′ 是 aGaG 的一个拓扑序,直接求最大字典序拓扑序即可。
证明见 AGC001F。
因此我们考虑在不互质的值之间连一条边,接下来我们可以通过 pp 来为这些边定向为一个 DAG,要求最小化最大拓扑序(字典序)。
将每个连通块最小的 AuAu 拿出来,并对所有它为定向的边定出向,在去掉 uu 之后它的出边连向的点不在一个连通块里,可以直接对出边连向的继续定向,但是若考虑这些出边连向了同一个连通块,则这些边不好定向。
考虑我们的目的:最小化下一步最大能拿到的数,于是在拿走这个数后,这个点为定向的出边会产生若干个连通块,每个连通块有若干个数变得“可能可以访问”,我们想让“可能可以访问的小的数”向“可能可以访问的大的数”尽可能地有连边,所以我们拿出连通块里面最小的后继,继续递归定向最小的后继的所有边为出边。
FF
感觉是简单的。
观察到我们如果把棋子移到一个数更小的点,且它没有其它出路,我们就赢了:对方会把棋子移回来,而对方的数一定比我们先用完。
而我们移动向一个不小于自己的点,一定是不优的:对方能给你移回来,而你始终无法突破这个点,即始终无法使得对方必须把棋子移动向其他方向,对方总是可以移回来,你还先死。
所以接下来问题变为:每一步可以将棋子挪向一个相邻的 aiai 更小的点,不能移动者输,将边定向,变为一个 DAG 上的有向图游戏,容易判断胜负。
本文已经结束了。本文作者:ღꦿ࿐(DeepSea),转载请注明原文链接:https://www.cnblogs.com/Dreamerkk/p/18157316,谢谢你的阅读或转载!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步