神奇的矩阵 NOI模拟题

神奇的矩阵

题目大意

有一个矩阵(A),第一行是给出的,接下来第(x)行,第(y)个元素的值为数字(A_{x-1,y})({A_{x-1,1},A_{x-1,2},A_{x-1,3},cdots,A_{x-1,y}})出现的次数。

现在有修改及询问操作:

  • 修改第一行的一个元素
  • 询问矩阵某个位置的值

要点

这个矩阵果然神奇,第(x(xgeq 4))和第(x-2)行是一样的。这个举个例子就知道了。

现在,我们只需要关心前(3)行就可以了。

算法1

这个是标答。

先分块,然后维护两个数组:

  • sum1[i][j]:第(1)行,前(i)块数字(j)出现了多少次(由于第一行的数字可能很大,我们可以离散化)。
  • sum2[i][j]:第(2)行,前(i)块数字(j)出现了多少次。

先看修改:

当一个地方的数字改变时,假设由(a)变为(b)
sum1直接搞搞就好。我们来看看sum2

举个例子:假设第一行是这样的

b a c a | a a a d | d a d a a a
1 1 1 2   3 4 5 1   2 6 3 7 8 9

|表示分块,假设第(6)个数由(a)变为(b),我们来看看第(2)行的变化:

b a c a | a b a d | d a d a a a
1 1 1 2   3 2 4 1   2 5 3 6 8 7

再简单一点,我们看看关于数字(a)的变化:

* a * a | a a a * | * a * a a a
* 1 * 2   3 4 5 *   * 6 * 7 8 9
* a * a | a # a * | * a * a a a
* 1 * 2   3 # 4 *   * 5 * 6 7 8

这样我们就可以知道去掉一个数该如何修改sum1了:假设这个数在第(i)块,那么对于所有的(jgeq i),第(j)块只是少了一个数,减去就好了。添加一个数同理。有了删除和添加,那么修改=删除+添加

再看询问,这个有了那两个数组,怎么搞都可以吧!

算法2

莫队算法。

每个状态为((y, k)),表示经历了(k)个操作之后,处在第(y)列。我们要维护第一行前(y)个数每个数字各出现了多少次,以及第二行前(y)个数每个数字各出现了多少次(这个可以利用算法1的手段)。

然后采用经典的莫队做法,时间复杂度:(O(n sqrt n))

感觉自己对莫队算法的思想了解还不够。。

原文地址:https://www.cnblogs.com/wangck/p/4607691.html