Uva 1386 - Cellular Automaton ( 矩阵乘法 + 循环矩阵 )
#include <cstdio> #include <cstring> #define CLR( a, b ) memset( a, b, sizeof(a) ) int MOD; #define MAX_SIZE 500 struct Mat { int n; LL mat[MAX_SIZE][MAX_SIZE]; Mat( int _n = 0 ) { n = _n; CLR( mat, 0 ); } void init() { for( int i = 0; i < n; ++i ) for( int j = 0; j < n; ++j ) mat[i][j] = ( i == j ); } Mat operator + ( const Mat &b ) const { Mat t( n ); for( int i = 0; i < n; ++i ) for( int j = 0; j < n; ++j ) t.mat[i][j] = ( mat[i][j] + b.mat[i][j] ) % MOD; return t; } Mat operator * ( const Mat &b ) const { Mat t( n ); for( int k = 0; k < n; ++k ) for( int i = 0; i < n; ++i ) if( mat[i][k] ) for( int j = 0; j < n; ++j ) t.mat[i][j] = ( t.mat[i][j] + mat[i][k] * b.mat[k][j] ) % MOD; return t; } void debug() { for( int i = 0; i < n; ++i ) { for( int j = 0; j < n; ++j ) { if( j !=0 ) putchar( ‘ ‘ ); printf( "%d", mat[i][j] ); } putchar( ‘\n‘ ); } } }; Mat fast_mod( Mat a, int b ) { Mat c( a.n ); c.init(); while( b ) { if( b & 1 ) c = c * a; a = a * a; b >>= 1; } return c; } void scan( int &x ) { char c; while( c = getchar(), c < ‘0‘ || c > ‘9‘ ); x = c - ‘0‘; while( c = getchar(), c >= ‘0‘ && c <= ‘9‘ ) x = x * 10 + c - ‘0‘; } void Orz() { int n, d, k; while( ~scanf( "%d %d %d %d", &n, &MOD, &d, &k ) ) { Mat c( n ); for( int i = 0; i < n; ++i ) scan( c.mat[i][0] ); Mat t( n ); for( int i = 0; i < n; ++i ) { t.mat[i][i] = 1; for( int j = 1; j <= d; ++j ) { int t1 = i - j; int t2 = i + j; if( t1 < 0 ) t1 += n; t.mat[i][t1] = 1; if( t2 > n-1 ) t2 -= n; t.mat[i][t2] = 1; } } //t.debug(); t = fast_mod( t, k ); t = t * c; for( int i = 0; i < n; ++i ) { if( i != 0 ) putchar( ‘ ‘ ); printf( "%d", t.mat[i][0] ); } putchar( ‘\n‘ ); } } int main() { Orz(); return 0; }
开始写的错误代码
#include <cstdio> #include <cstring> #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MAXN 500 typedef long long LL; int n, d, k, MOD; LL A[MAXN], B[MAXN]; void mul( LL *a, LL *b ) { LL c[MAXN] = {0}; for( int i = 0; i < n; ++i ) for( int j = 0; j < n; ++j ) c[i] += a[j] * b[ i <= j ? ( j - i ) : ( n - i + j ) ]; for( int i = 0; i < n; ++i ) a[i] = c[i] % MOD; } void fast_mod( int b ) { while( b ) { if( b & 1 ) mul( A, B ); mul( B, B ); b >>= 1; } } void scan( LL &x ) { char c; while( c = getchar(), c < ‘0‘ || c > ‘9‘ ); x = c - ‘0‘; while( c = getchar(), c >= ‘0‘ && c <= ‘9‘ ) x = x * 10 + c - ‘0‘; } int main() { while( ~scanf( "%d %d %d %d",&n, &MOD, &d, &k ) ) { CLR( A, 0 ); CLR( B, 0 ); for( int i = 0; i < n; ++i ) scan( A[i] ); for( int i = -d; i <= d; ++i ) B[( i + n ) % n ] = 1; fast_mod( k ); for( int i = 0; i < n; ++i ) { if( i != 0 ) putchar( ‘ ‘ ); printf( "%lld", A[i] ); } putchar( ‘\n‘ ); } }
AC代码君-细节的东西自己注意吧
时间: 2024-10-25 20:53:33