码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 2671 -Cryptography ( 矩阵乘法 + 线段树 )

时间:2014-10-21 00:46:33      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   strong   

 

ZOJ 2671 - Cryptography ( 矩阵乘法 + 线段树 )

 

 

题意:

给定模数r, 个数n, 询问数m

然后是n个矩阵,每次询问,输出矩阵联乘之后的结果。

 

分析:

矩阵乘法 + 线段树优化

这里线段树只有询问没有更新操作。

 

PS:顺便仰慕一下watashi。。。。

 

代码:

bubuko.com,布布扣
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lson l, m, o << 1
#define rson m + 1, r , o << 1 | 1
#define ls o << 1
#define rs o << 1 | 1
#define rt l, r , o
#define CLR( a, b ) memset( a, b, sizeof(a) )
#define MID ( l + r ) >> 1
#define MAXN 30003

int r, m, n, ll, rr;

struct Mat
{
    int mat[2][2];
    void set( Mat M )
    {
        for( int i = 0; i < 2; ++i )
            for( int j = 0; j < 2; ++j )
                mat[i][j] = M.mat[i][j];
    }
    void init()
    {
        for( int i = 0; i < 2; ++i )
            for( int j = 0; j < 2; ++j )
                mat[i][j] = ( i == j );
    }
    
}Tree[ MAXN << 2 ], M;

Mat mul( Mat a, Mat b )
{
    Mat c;
    CLR( c.mat, 0 );
    for( int i = 0; i < 2; ++i )
        for( int j = 0; j < 2; ++j )
            for( int k = 0; k < 2; ++k )
                c.mat[i][j] = ( c.mat[i][j] + a.mat[i][k] * b.mat[k][j] ) % r;
    return c;
}

inline void push_up( int o )
{
    Tree[ o ] = mul( Tree[ls], Tree[rs] ); 
}

void build( int l, int r, int o )
{
    Tree[o].init();
    if( l == r )
    {
        for( int i = 0; i < 2; ++i )
            for( int j = 0; j < 2; ++j )
                scanf( "%d", &M.mat[i][j] );
        Tree[o].set( M );
        return;
    }
    int m = MID;
    build( lson );
    build( rson );
    push_up( o );
}

Mat query( int L, int R, int l, int r, int o )
{
    if( L <= l && r <= R )
        return Tree[o];
    int m = MID;
    if( R <= m )    return query( L, R, lson );
    else if( L > m )    return query( L, R, rson );
    else 
    {
        return mul( query( L, m, lson ), query( m + 1, R, rson ) );
    }
}

void Orz()
{
    int cas = 0;
    while( ~scanf( "%d %d %d", &r, &n, &m ) )
    {
        if( cas != 0 )
            putchar( \n );
        cas++;
        build( 1, n, 1 );
        bool blank = false;
        while( m-- )
        {            
            if( blank )    putchar( \n );    
            else    blank = true;
            scanf( "%d %d", &ll, &rr );
            Mat res = query( ll, rr, 1, n, 1 );        
            for( int i = 0; i < 2; ++i )
                printf( "%d %d\n", res.mat[i][0], res.mat[i][1]);
        }
    }
}

int main()
{
    Orz();
    return 0;
}
代码君

 

ZOJ 2671 -Cryptography ( 矩阵乘法 + 线段树 )

标签:style   blog   http   color   io   os   ar   for   strong   

原文地址:http://www.cnblogs.com/BigBallon/p/4039118.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!