AGC#30 D
题意:有一个长度为 (N(leq 3000)) 的序列。有 (Q(leq 3000)) 个操作 ((x_i,y_i))。每个操作可以选择是否执行;若执行,则交换 (A_{x_i}) 和 (A_{y_i})。一共有 (2^Q) 种选择方法。问所有选择方法最终序列里的逆序对数量之和是多少。模一个大质数。
题解:这题容易陷入思维僵局。比如先枚举某一个位置 (k),然后设 (f_{i,j}) 表示到第 (i) 个操作,我们关注的那个数字现在在 (j) 的期望/总方案数。最后枚举两个数合成,总复杂度是 (O(N^2Q))。其实每次操作很“稀疏”(只和两个位置有关),但是这种方法却必须维护好所有位置。
标准做法是,设 (f_{t,i,j}) 表示进行了 (t) 轮后,当前第 (i) 个位置的数字大于第 (j) 个的概率。每次转移时发现,只有其中一个数字是 (x_i) 或 (y_i) 的位置 ((i,j)) 才会被修改,别的直接继承(这也是为什么要用概率来表示,因为概率是直接继承,方案数要集体乘 (2))。每次修改的状态数只有 (O(N)) 个,所以总复杂度降为 (O(NQ))。
AGC#30 E
题意:给出两个长度为 (N(leq 5000)) 的 (01) 序列 (s) 和 (t),保证它们其中任意三个连续数字不可能全相同。每次可以翻转 (s) 中的一位,但必须实时满足这一限制。问最少几步可以把 (s) 变为 (t)。
题解:刚开始感觉可以DP,记一下前几位数字怎么选,从左到右dp过去。后来感觉应该将 (01) 序列划成一段段的,不能无脑DP。
题解的解释十分形象。我们在所有 (01) 交界处都划上线(为了后续分析的方便,开头前和结尾处还要花上无穷多的线)。由实时的限制我们知道,中间任意两条线直接的距离必然是 (1) 或 (2)。每次翻转一位 (01),相当于将一根线向左/右移动。假设我们知道了 (s) 和 (t) 串线的一一对应关系,可以证明,移动步数的下界((sum |pos_i-pos_j|))必然能取到,这样我们只需 (O(N)) 扫一遍即出解。因为线是 (O(N)) 条,所以最多只会有 (O(N)) 种有效的对应关系,直接枚举即可。*线的对应关系好像还存在三分性,可以进一步优化速度。