Codeforces Round #468 Div. 1

  D:首先考虑如果给定白棋位置,如何判断胜负。黑棋获胜需要四个方向都有能贴上白棋的棋子。由于每一轮都必须移动,显然先对平面黑白染色一下,只有与白棋所在格异色的黑棋才需要考虑。考虑让一个黑棋去贴上白棋某个方向,那么能贴上的条件是该方向坐标之差>另一方向坐标之差。因为如果其往这边逃的话,这样才有足够的时间冲过去拦住。若往其他方向逃,只要模仿其动作即可,处于逃跑方向的棋子会对其作出制裁。

  可以发现每个黑棋对每个位置的白棋都只有一种能将其锁死的方向,四个方向的分界线形成一个X形。于是现在要数的是被任意四个黑棋的不同方向包含的白棋数量。

  斜着的东西很难考虑,把坐标系旋转一下45°,分界线就变成了一个十字形,就看起来非常舒服了。这样的话扫描线扫过去,维护线两边的黑棋纵坐标上下界,两边上界取min下界取max即可得到该直线上的被锁死的白棋纵坐标上下界。

  E:将每个限制存储在其右端点上,记录最靠右的li,0、li,1表示li,j到i至少要有一个j。设f[i][0/1]为第i位是0/1且满足所有右端点在i及i之前的限制的序列数量。转移考虑枚举最后一段连续0/1有多长,不妨考虑0,即有f[i][0]=Σf[j][1] (j>=max{lj~i,1})。前缀和一下,二分一下转移的最远点(直接移动指针难以更新max{l}),即可做到O(klogk)。

  注意到当一个点不存在限制时,f[i][0]=f[i][1]=f[i-1][0]+f[i-1][1]。如果连续一段没有限制,dp值会构成公比2的等比数列。于是考虑离散化后dp。然后应该和上面的dp没有什么太大的区别。

  可是为什么想想就很难写啊。咕咕咕。有缘再补(?)

猜你喜欢

转载自www.cnblogs.com/Gloid/p/10440264.html