【ZOJ】2671 Cryptography 线段树

传送门:【ZOJ】2671 Cryptography


题目分析:线段树水题。


代码如下:


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

typedef long long LL ;

#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define rep( i , a , b ) for ( int i = ( a ) ; i <  ( b ) ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define clr( a , x ) memset ( a , x , sizeof a )
#define cpy( a , x ) memcpy ( a , x , sizeof a )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define rt o , l , r
#define root 1 , 1 , n
#define mid ( ( l + r ) >> 1 )

const int O = 2 ;
const int MAXN = 30005 ;
int mod ;

struct Matrix {
	int mat[O][O] ;
	int n ;
	
	Matrix () {}
	
	Matrix ( int n ) : n ( n ) {
		clr ( mat , 0 ) ;
	}
	
	void clear () {
		clr ( mat , 0 ) ;
	}
	
	void init () {
		rep ( i , 0 , n ) rep ( j , 0 , n ) mat[i][j] = i == j ;
	}
	
	void show () {
		rep ( i , 0 , n ) rep ( j , 0 , n ) printf ( "%d%c" , mat[i][j] , j < n - 1 ? ' ' : '\n' ) ;
	}
	
	Matrix operator * ( const Matrix& a ) const {
		Matrix res ( n ) ;
		rep ( i , 0 , n ) rep ( j , 0 , n ) rep ( k , 0 , n ) {
			res.mat[i][j] = ( res.mat[i][j] + mat[i][k] * a.mat[k][j] ) % mod ;
		}
		return res ;
	}
	
	Matrix operator *= ( const Matrix& a ) const {
		return ( *this ) * a ;
	}
} T[MAXN << 2] ;

int n , m ;

void scanf ( int& x , char c = 0 ) {
	while ( ( c = getchar () ) < '0' || c > '9' ) ;
	x = c - '0' ;
	while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ;
}

void build ( int o , int l , int r ) {
	if ( l == r ) {
		T[o].n = 2 ;
		rep ( i , 0 , 2 ) rep ( j , 0 , 2 ) scanf ( T[o].mat[i][j] ) ;
		return ;
	}
	int m = mid ;
	build ( lson ) , build ( rson ) ;
	T[o] = T[ls] * T[rs] ;
}

Matrix query ( int L , int R , int o , int l , int r ) {
	if ( L <= l && r <= R ) return T[o] ;
	int m = mid ;
	if ( R <= m ) return query ( L , R , lson ) ;
	if ( m <  L ) return query ( L , R , rson ) ;
	return query ( L , R , lson ) * query ( L , R , rson ) ;
}

void solve () {
	int L , R ;
	build ( root ) ;
	while ( m -- ) {
		scanf ( L ) , scanf ( R ) ;
		query ( L , R , root ).show () ;
		if ( m ) putchar ( '\n' ) ;
	}
}

int main () {
	bool flag = 0 ;
	while ( ~scanf ( "%d%d%d" , &mod , &n , &m ) ) {
		if ( flag ) putchar ( '\n' ) ;
		flag = 1 ;
		solve () ;
	}
	return 0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值