题意:
给一个数组A[1,2,...,n]和m个查询l,r
对于每一个查询,
1 <= A[i] <= 10^9
1 <= n,m <= 10^5
每一步骤均对 MOD = 10^9+7 取模
方法一:复杂度O(n+m*log(MOD))
看到递推公式,不难想到递推公式
当我们给一个查询L,R时,
这里解矩阵[X]有两种方法:
(1)建立二元同余方程组(由于每次取模,所以是同余方程组而不是方程组)
(2)[X] = matrix[R] * matrix[L+1](-1),求逆再相乘
对于(1),可以用用扩展欧几里得解出(写出来有BUG。。。)
对于(2),2*2矩阵的逆:
(写出来很快。。)
方法二:O(nlog(n)+mlog(n))
线段树的方法,记
给一个数组A[1,2,...,n]和m个查询l,r
对于每一个查询,
F[l] = A[l]
F[l+1] = A[l+1]
F[x] = F[x-1] + A[x]*F[x-2], x >= l+2
求F[r]。
1 <= A[i] <= 10^9
1 <= n,m <= 10^5
每一步骤均对 MOD = 10^9+7 取模
方法一:复杂度O(n+m*log(MOD))
看到递推公式,不难想到递推公式
[F[n+2]] = [1 A[n+2]] * [F[n+1]] = ... = [1 A[n+2]] * [1 A[n+2]] * ... * [1 A[3]] * [F[2]]
[F[n+1]] [1 0 ] [F[n] ] [1 0 ] [1 0 ] [1 0 ] [F[1]]
记
matrix[n] = [1 A[n]] * [1 A[n-1]] * ... * [1 A[3]]
[1 0 ] [1 0 ] [1 0 ]
其中n>=3,matrix[n]是一个2*2的矩阵
则
[F[n] ] = matrix[n] * [F[2]]
[F[n-1]] [F[1]]
其中n>=3
当我们给一个查询L,R时,
[F[R] ] = matrix[R] * [f[2]]
[F[R-1]] [f[1]]
[F[L+1]] = matrix[L+1] * [f[2]]
[F[L] ] [f[1]]
要求2*2的矩阵[X]使得,
[f[R] ] = [X] * [f[L+1]]
[f[R-1]] [f[L] ]
等价于
matrix[R] * [f[2]] = [X] * matrix[L+1] * [f[2]]
[f[1]] [f[1]]
所以应该是 matrix[R] = [X] * matrix[L+1]
这里解矩阵[X]有两种方法:
(1)建立二元同余方程组(由于每次取模,所以是同余方程组而不是方程组)
(2)[X] = matrix[R] * matrix[L+1](-1),求逆再相乘
对于(1),可以用用扩展欧几里得解出(写出来有BUG。。。)
对于(2),2*2矩阵的逆:
[a b]-1 = 1/(ad-bc) * [d -b]
[c d] [-c a]
然而,模运算不支持除法,但是,除以一个数x在MOD下等价于乘以逆元x^(MOD-2)
(写出来很快。。)
方法二:O(nlog(n)+mlog(n))
线段树的方法,记
M[n] = [1 A[n]]
[1 0 ]
显然,
[F[R] ] = M[R] * ... * M[L+2] * [F[L+1]]
[F[R-1]] [F[L] ]
为了方便求出M[R] * ... * M[L+2],可以建立线段树