zoukankan      html  css  js  c++  java
  • 「UVA12183」Top Secret

    题目

    点这里看题目。

    分析

    可以发现题目提到的 decryption 其实就是一个线性变换:

    [M= egin{bmatrix} 1&R&0&dots&0&L\ L&1&R&dots&0&0\ 0&L&1&dots&0&0\ vdots&vdots&vdots&ddots&vdots&vdots\ 0&0&0&dots&1&R\ R&0&0&dots&L&1 end{bmatrix} ]

    如果直接算矩阵乘法,复杂度是 (O(n^3log S)) 的,无法接受。

    注意到 (M) 是一个循环矩阵,这意味着我们可以将它拆解为多项式的形式:

    [egin{aligned} M&=E^0+RE^1+LE^{n-1}\ E&= egin{bmatrix} 0&1&0&dots&0&0\ 0&0&1&dots&0&0\ 0&0&0&dots&0&0\ vdots&vdots&vdots&ddots&vdots&vdots\ 0&0&0&dots&0&1\ 1&0&0&dots&0&0 end{bmatrix} end{aligned} ]

    对于多项式做循环卷积,接着我们就可以还原出 (M^S)。这样复杂度就是 (O(n^2log S)) 的。

    小结:循环矩阵比较少见,一般可以将它和多项式结合起来看

    代码

    #include <cstdio>
    
    #define rep( i, a, b ) for( int i = (a) ; i <= (b) ; i ++ )
    #define per( i, a, b ) for( int i = (a) ; i >= (b) ; i -- )
    
    const int MAXN = 1005;
    
    template<typename _T>
    void read( _T &x )
    {
    	x = 0; char s = getchar(); bool f = false;
    	while( s < '0' || '9' < s ) { f = ( s == '-' ), s = getchar(); }
    	while( '0' <= s && s <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar(); }
    	if( f ) x = -x;
    }
    
    template<typename _T>
    void write( _T x )
    {
    	if( x < 0 ) putchar( '-' ), x = -x;
    	if( 9 < x ) write( x / 10 );
    	putchar( x % 10 + '0' );
    }
    
    int mat[MAXN][MAXN];
    int F[MAXN], G[MAXN], tmp[MAXN];
    
    int A[MAXN];
    int N, S, L, R, X, mod;
    
    inline int Mul( int x, int v ) { return 1ll * x * v % mod; }
    inline int Sub( int x, int v ) { return ( x -= v ) < 0 ? x + mod : x; }
    inline int Add( int x, int v ) { return ( x += v ) >= mod ? x - mod : x; }
    
    void Convolute( int *ret, const int *P, const int *Q )
    {
    	rep( i, 0, N - 1 ) tmp[i] = 0;
    	rep( i, 0, N - 1 ) rep( j, 0, N - 1 )
    		tmp[( i + j ) % N] = Add( tmp[( i + j ) % N], Mul( P[i], Q[j] ) );
    	rep( i, 0, N - 1 ) ret[i] = tmp[i];
    }
    
    int main()
    {
    	int T;
    	read( T );
    	while( T -- )
    	{
    		read( N ), read( S ), read( L ), read( R ), read( X );
    		rep( i, 0, N - 1 ) read( A[i] );
    		mod = 1; rep( i, 1, X ) mod *= 10;
    		rep( i, 0, N - 1 ) G[i] = F[i] = 0;
    		G[0] = 1 % mod;
    		F[0] = 1 % mod, F[1] = R % mod, F[N - 1] = L % mod;
    		while( S )
    		{
    			if( S & 1 ) Convolute( G, G, F );
    			Convolute( F, F, F ), S >>= 1;
    		}
    		for( int i = 0 ; i < N ; i ++ )
    			for( int k = 0 ; k < N ; k ++ )
    				mat[k][( i + k ) % N] = G[i];
    		rep( i, 0, N - 1 )
    		{
    			int ans = 0;
    			rep( j, 0, N - 1 ) ans = Add( ans, Mul( mat[i][j], A[j] ) );
    			write( ans ), putchar( i == N - 1 ? '
    ' : ' ' );
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    2020 企业远程研发总结 —— 回首抗疫一年
    CODING X C-Life:云端 DevOps 加速企业数智化
    CODING 联合 TKE,让应用发布更便捷
    CODING 再携手腾讯云 Serverless,让开发者跑步上云
    代码托管从业者 Git 指南
    推荐计划 | 推荐好友用 CODING,获高额返现奖励
    仰望天空,脚踏实地 —— CODING OKR 全新上线
    在.NET中体验GraphQL
    C#规则引擎RulesEngine
    武装你的WEBAPI-OData常见问题
  • 原文地址:https://www.cnblogs.com/crashed/p/15339091.html
Copyright © 2011-2022 走看看