foj 1692 矩阵快速幂&&循环矩阵优化
2014-07-26 20:06
465 查看
这题首先要构造一个矩阵来模拟递推的过程 这是很简单的
难度在于即使这样用了快速幂优化之后还是会TLE
那么就需要继续优化
怎么优化呢?
通过观察可以发现我们构造的矩阵是循环矩阵。什么是循环矩阵呢?
形式为
的矩阵为循环矩阵
就是说下一行的值能够通过上一行的值右移得到
循环矩阵有一个性质就是:
对于两个循环矩阵 A 与 B 来说,A + B 也是循环矩阵。AB 也是循环矩阵,并且
AB=BA
因此可以优化矩阵的乘法 从o(n^3) 优化到o(n^2)
这样就不会TLE了
AC代码如下:
难度在于即使这样用了快速幂优化之后还是会TLE
那么就需要继续优化
怎么优化呢?
通过观察可以发现我们构造的矩阵是循环矩阵。什么是循环矩阵呢?
形式为
的矩阵为循环矩阵
就是说下一行的值能够通过上一行的值右移得到
循环矩阵有一个性质就是:
对于两个循环矩阵 A 与 B 来说,A + B 也是循环矩阵。AB 也是循环矩阵,并且
AB=BA
因此可以优化矩阵的乘法 从o(n^3) 优化到o(n^2)
这样就不会TLE了
AC代码如下:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int MAX_N = 101; __int64 MOD; int N, M, L, R; void multipy( __int64 a[][MAX_N], int am, int an, __int64 b[][MAX_N], int bm, int bn, __int64 c[][MAX_N] ){ for( int i = 1; i <= am; i++ ){ for( int j = 1; j <= bn; j++ ){ c[i][j] = 0; for( int k = 1; k <= an; k++ ){ c[i][j] = ( c[i][j] + a[i][k] * b[k][j] ) % MOD; } } } } void multipy1( __int64 a[][MAX_N], int am, int an, __int64 b[][MAX_N], int bm, int bn, __int64 c[][MAX_N] ){ for( int i = 1; i <= 1; i++ ){ for( int j = 1; j <= bn; j++ ){ c[i][j] = 0; for( int k = 1; k <= an; k++ ){ c[i][j] = ( c[i][j] + a[i][k] * b[k][j] ) % MOD; } } } for( int i = 2; i <= am; i++ ){ c[i][1] = c[i-1][bn]; for( int j = 2; j <= bn; j++ ){ c[i][j] = c[i-1][j-1]; } } } void get_pow( __int64 a[][MAX_N], __int64 n ){ __int64 ans[MAX_N][MAX_N] = {0}; __int64 temp[MAX_N][MAX_N]; for( int i = 1; i <= N; i++ ){ ans[i][i] = 1; } while( n ){ if( n % 2 == 1 ){ multipy1( ans, N, N, a, N, N, temp ); memcpy( ans, temp, sizeof( __int64 ) * MAX_N * MAX_N ); } multipy1( a, N, N, a, N, N, temp ); memcpy( a, temp, sizeof( __int64 ) * MAX_N * MAX_N ); n /= 2; } memcpy( a, ans, sizeof( __int64 ) * MAX_N * MAX_N ); } int main(){ int T; scanf( "%d", &T ); while( T-- ){ scanf( "%d%d%d%d%I64d", &N, &M, &R, &L, &MOD ); __int64 a[MAX_N][MAX_N]; __int64 b[MAX_N][MAX_N]; __int64 c[MAX_N][MAX_N]; memset( a, 0, sizeof( a ) ); memset( b, 0, sizeof( a ) ); memset( c, 0, sizeof( a ) ); for( int i = 1; i <= N; i++ ){ scanf( "%I64d", &b[i][1] ); } a[1][2] = R % MOD; a[1] = L % MOD; a [1] = R % MOD; a [N-1] = L % MOD; for( int i = 2; i < N; i++ ){ a[i][i-1] = L % MOD; a[i][i+1] = R % MOD; } for( int i = 1; i <= N; i++ ){ a[i][i] = 1; } get_pow( a, M ); multipy( a, N, N, b, N, 1, c ); printf( "%I64d", c[1][1] ); for( int i = 2; i <= N; i++ ){ printf( " %I64d", c[i][1] ); } puts(""); } return 0; }
相关文章推荐
- HDU 2276 & FZU 1692 (矩阵快速幂+循环同构优化)
- hdu 2276 矩阵快速幂&&循环矩阵优化
- 多校第九场:贪心+矩阵快速幂中间优化+线性递推&线段树递推
- Cellular Automaton UVA - 1386 矩阵快速幂 & 循环矩阵
- 【矩阵乘法】【快速幂】【递推】斐波那契数列&&矩乘优化递推模板
- 利用矩阵&快速幂解决斐波那契数列相关题目小结
- 矩阵快速幂(特殊矩阵+优化)upc2604
- poj3150 && LA3704 Cellular Automaton 矩阵乘法 + 循环矩阵性质
- mysql快速优化<一>
- HDU3221Brute-force Algorithm(矩阵快速幂&&指数降幂)
- fzu 1692 Key problem(循环同构矩阵o(n^2)优化乘法)
- hdu 2276 Kiki & Little Kiki 2(矩阵优化递推)
- FOJ 1683 纪念SlingShot(矩阵快速幂)
- Poj 3150 Cellular Automaton(矩阵快速幂, 循环矩阵快速幂)
- hdu 2276 Kiki & Little Kiki 2 矩阵/循环矩阵
- 【优化&大师级代码欣赏】Codeforces Round #137 (Div. 2) / 222B Cosmic Tables (矩阵)
- POJ 3735 Training little cats 解题报告(矩阵构造+快速幂优化)
- LightOJ 1052 String Growth && uva 12045 Fun with Strings (矩阵快速幂)
- FOJ 1617 Hero's matrix(矩阵乘法,将3次方复杂度变为二次方)
- UVa 11300 Spreading the Wealth (使用方程进行等价转化&快速选择优化)