A. 灯
容易发现问题是连通块数,因为原图是树,可以用点数(为$1$的点)减边数(连接相邻的为$1$的点的边)表示。
点数是易于维护的,所以问题是维护边数。
考虑一个情况,每种颜色的出现次数都很少,那么可以直接在原序列上暴力。
另一种情况,每种颜色的出现次数都很多,并且颜色总数不多。
那么可以预处理出颜色两两之间的贡献,维护当前为$1$的颜色,每次暴力扫每种颜色,来得到当前获得的边数。
结合两种情况,考虑根号分治。
问题还有小颜色与大颜色之间的边的贡献。
这个顺便统计就好了,一个常用的套路是提前维护。
B. 十字路口
一个很神仙的操作是,将大小的对应关系转化到边上。
设$x_i$表示第$i$次观察的时间(对于周期取$mod$)。
根据同一个路灯多次被观察,可以得到$x_i-x_j=k$的关系,注意这个方程也是在$mod$周期意义下的。
考虑建边$(i,j)$,边权为$k$。
可以发现任意一个环都是周期的倍数。
可以理解,最小环就是合法的周期。
所以可以通过$floyd$求最小环,这样的复杂度是$O(m^2n+m^3)$。
转化一下,令$y_i$表示第$i$个路灯被观察的相对时间。
根据同时观察多个路灯,也可以列出一些方程,建出对应的边。
同样跑最小环,这样的复杂度是$O(n^2m+n^3)$,结合两个算法,复杂度就对了。
正解是将暴力的建图,转化为将权值(也就是被观察的时间)排序,再对每组相邻的权值建边。
然后任意一个简单环都是解,不知道为什么这样是正确的。
C. 密室逃脱
是一个非常神的$dp$。
设$f_{i,j}$表示当前考虑到第$i$个房间,恰好有$j$个人可以到达第$i$个房间的条件下前$i$个房间能放的最大的人数。
可以考虑一下转移,实际上就是在合法的前提下,考虑每种情况。
如果$j<a_i$,那么左侧的人一个都过不去。
分两种情况讨论,若右侧的人过不来,那么可以转移到$f_{i+1,0~b_i-1}$。
若右侧的人能过来,那么可以转移到$f_{i+1,j+b_i}$,即右侧的人为了过来,留下了$b_i$个人,但是左侧的人不够开门了。
如果$a_i<=j<a_i+b_i$,因为现在的人已经够开左侧门的了,所以只有一种情况,即这边留下了$a_i$个人开着门,剩下的人过去,即转移到$f_{i+1,j-a_i}$。
如果$j>=a_i+b_i$,那么左侧右侧都可以开门,所有人都能过去,只能转移到$f_{i+1,j}$。
这样分析过来,发现只有第一种情况需要给$f$数组加上一个值,也就是可以在这个位置放上一些人。