直接两维做的话肉眼可见的阴间,但发现由 ((r,c)) 合法可以推出 ((r,m)) 及 ((n,c)) 合法,而且反着来也是成立的。
这样问题就转化成了求有多少个 (r) 满足 ((r,m)) 合法以及多少个 (c) 满足 ((n,c)) 合法。
一种简单的思路就是对于每一个 (n) 或 (m) 的因数暴力判断,设每次判断的询问次数为 (t) ,询问次数就为 (tcdot lfloor log_2 (n+m) floor) 。
现在的任务就转化成了让 (t) 降为 ( ext{3}) 。
(为了方便,一下内容讨论二元组 ((r,m)) 的情况)。
很容易想到,这样只要判断以 ((1,1)) 为左上角和以 ((r+1,1)) 为坐上角的两个子矩阵是否相等就行了。
但是不允许询问相交矩阵,但上述判断提供了一条思路,即通过判断两个子矩阵和分别和另一个子矩阵是否相等来判断这两个子矩阵相等。
设在区间 ([1,D]) 中被分成的矩阵个数为 (T = frac{D}{r}) 。
-
对于 (T = 2) 的情况,直接判断这两个子矩阵是否相等即可。
-
对于 (T eq 2) 的情况,因为 (T) 都是质因数,而 (T= ext{2}) 的情况已经讨论过了,所以 (T) 必为奇数,可以将区间分成三段: ([1,frac{T-1}{2} imes r]) , ([frac{T+1}{2} imes r, D - r]) , ([frac{T+3}{2} imes r,D]) 。可以发现后两段与第一段没有交集,所以可以将第一段和后两段分别询问来得出这个 (r) 是否合法。
这样询问次数已经小于或等于题目要求的 (3 cdot left lfloor{ log_2{(n+m)} } ight floor) 了。
Code(C++): Link.