T1:这题是一道水题,但是我没有想出来。
首先发现如果一个矩阵的(1,1)为1的话,那么先手可以先把(1,1)翻转,然后每次后手翻转另一个位置的时候,先手就可以翻转(1,1)。这样下来先手在这个矩阵是必胜的。反之,如果一个矩阵的(1,1)是0,那么先手是必败的。这样我们就可以知道一个矩阵的胜负状态。然后把所有矩阵的胜负状态异或起来就是总的胜负状态了。
T2:这题是一个矩阵乘法。
首先我们二分答案,设a[i]表示i号房间能走到的最高楼层。现在关键就是要求出对于mid的a数组,然后判断一下有没有>=m的就可以了。
而求a的时候要用到矩阵乘法。不过这题不能用普通的矩乘,要优化一下。
首先预处理出一个数组:g[d][i][j]表示从i号房到j号房走2^d步能上升的最大楼层。求g的时间复杂度是n^3*log的。
然后在用g去求二分时的矩阵,这样的二分时间复杂度就是n^2*log^2的了。
T3:这题还是一个矩阵乘法。
首先我们要新建k个点,然后原来的i点向新建的j点连out[i][j],而j点向i点连in[i][j],那么我们发现在n点中走不超过d就等同于在新图中走不超过2d。并且我们可以从一个新建的点走到另一个新建的点,这样我们就把一个n*n的矩阵转化成一个k*k的矩阵。接下来要做的就是直接矩乘。
不过这题的一个难点就是要求的是0~d步的矩阵的前缀和。下面有一种在快速幂中巧妙求和的方法:
while(w>=1)
{
if(w%2==1)
{
s=s*f+g
}
g=g*f+g
f=f*f
w/=2;
}
其中s是求前缀和矩阵,f是2^i的次幂矩阵,g是1~2^i的矩阵。具体为什么这样是对的手推一下就可以了。
至此这题就做完了。