Algorithm 具有(最大2个)1'连续块的二进制矩阵;s作为行,计算其平方的轨迹

Algorithm 具有(最大2个)1'连续块的二进制矩阵;s作为行,计算其平方的轨迹,algorithm,matrix,linear-algebra,Algorithm,Matrix,Linear Algebra,设A为nxn二进制矩阵,其行的形式为0^k1^l0^m或1^k0^l1^m。而且,A沿对角线有零。尺寸n最多可为10^5。矩阵将通过给出1块开始和结束的索引给出 换句话说,这些行是由0包围的1运行或由1包围的0运行。一行可以全部为零,但不能全部为1(对角线上为零) 示例A: [0, 0, 0, 0, 1, 1, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 1, 1, 0, 0] [0, 0, 0, 1, 1, 1, 1, 1, 1, 1] [1, 1, 1, 0, 0, 0,

A
nxn
二进制矩阵,其行的形式为
0^k1^l0^m
1^k0^l1^m
。而且,
A
沿对角线有零。尺寸n最多可为
10^5
。矩阵将通过给出
1
块开始和结束的索引给出

换句话说,这些行是由
0
包围的
1
运行或由
1
包围的
0
运行。一行可以全部为零,但不能全部为1(对角线上为零)

示例
A

[0, 0, 0, 0, 1, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 1, 0, 0]
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 0, 0, 0, 0, 1, 1, 1]
[1, 0, 0, 0, 0, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 1]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 0, 0, 0, 0, 1, 1]
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
如何高效地计算
A^2
的轨迹(在
O(n^2)
时间下)

这相当于求A的特征多项式的
(n-2)
和系数,表示它
g_2(A)
,因为

tr(A^2) = (tr A)^2 - 2g_2(A) = -2g_2(A)

这个问题的起因是:

我们得到了[1..n]的一个置换p,并且对数量感兴趣

r(p) = #{k | p^{-1}[k+1] < p^{-1}[k]}
r(p)={k|p^{-1}[k+1]
这里
p^{-1}[k]
表示
p
k
的索引。我们要计算两个元素的所有互换,这两个元素将r减少2。这可以通过考虑每个指数
k
来实现,其中
p[k]
是有利的。它取决于
p[k]-1
p[k]+1
的位置(仅在边缘情况下的另一个位置),这就是行的形式来源。但是另一个元素的移动也应该是有益的,因此问题变成了矩阵
A
中有多少个元素同时具有
A[i][j]
A[j][i]
等于
1
,并且我们要计算
A^2
的轨迹。此外,在原始问题中,我们想从中减去相邻数
(|p[i]-p[j]|==1)
,因为这不会将
r
减少2,而只会减少1。但这可以在线性时间内完成,为了简单起见,这个问题不考虑。虽然,原始问题可能对矩阵
A
施加了一些进一步的限制,这有助于计算(?)

这可以在O(n logn)时间内使用A完成


该算法按顺序计算乘积对角线的条目。它维护一个包含当前列的Fenwick树。Fenwick树可以在时间O(logn)中更新条目,并在时间O(logn)中报告子数组和。对于{i}×{j…j'-1}位置的每一部分行,我们创建两个事件,(j,i,+1)和(j',i,-1)。按事件的第一个条目(列,也称为时间)对事件进行排序和分组。事件(j,i,Δ)是指在时间j时,将条目i增加Δ。要计算对角线元素索引k,首先应用时间为k的所有事件,然后报告相应行中的所有事件间隔,并求和。

这似乎是可能的,但并不容易。^2的每个条目都是A的行和列的标量积;的行遵循简单的结构,但列不遵循。我们需要一种方法来有效地计算给定范围内有多少行在给定列中有一个1,因此从这个意义上讲,这更多的是一个数据结构问题,而不是一个算法问题。另一个想法是分解
a=(L+M+R)
,其中
L
是行开头只有1的矩阵,
M
在行的中间只有1,而
R
在行的末尾只有1。
A^2=(L+M+R)(L+M+R)
的扩展需要九次乘法而不是一次乘法,但是每一次乘法的形式都比较简单,因此可能更容易找到次二次时间算法。谢谢,这太棒了!不幸的是,我没有足够的repu来提供+1。原始问题的解决时间从19分钟增加到6秒:D