POJ3233矩阵乘法

Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;


public class Main {
	public static void main(String args[]) {
		new Task().solve() ; 
	}
}

class Task{
	InputReader in = new InputReader(System.in) ;
	PrintWriter out = new PrintWriter(System.out) ;
	
	int Mod ;
	int size ;
	
	class Mat{
		int[][] val ;
		Mat(){
			val = new int[size+1][size+1] ;
		}
		Mat E(){
			for(int i = 1 ; i <= size ; i++){
				Arrays.fill(val[i] , 0) ;
			    val[i][i] = 1 ;
			}
			return this ;
		}
		Mat O(){
			for(int i = 1 ; i <= size ; i++){
				Arrays.fill(val[i] , 0) ;
			}
			return this ;
		}
	}
	
	Mat mult(Mat A , Mat B){
		Mat S = new Mat().O() ;
		for(int i = 1 ; i <= size ; i++){
			for(int j = 1 ; j <= size ; j++){
				for(int k = 1 ; k <= size ; k++){
					S.val[i][j] = (S.val[i][j] + A.val[i][k] * B.val[k][j]) % Mod  ;
				}
			}
		}
        return S ;		
	}
	
	Mat pow(Mat A , int k){
		Mat S = new Mat().E() ;
		for(; k > 0 ; k >>= 1){
			if((k & 1) > 0)
				S = mult(S , A) ;
			A = mult(A , A) ;
		}
		return S ;
	}
	
	void solve(){
	    int n = in.nextInt() ;
	    int k = in.nextInt() ;
	    Mod = in.nextInt() ;
	    int[][] a = new int[n+1][n+1] ;
	    for(int i = 1 ; i <= n ; i++){
	    	for(int j = 1 ; j <= n ; j++) a[i][j] = in.nextInt() ;
	    }
	    size = n<<1 ;
	    Mat A = new Mat().O() ;
	    for(int i = 1 ; i <= n ; i++){
	    	for(int j = 1 ; j <= n ; j++){
	    		A.val[i][j] = a[i][j] ;
	    	}
	    	A.val[n+i][i] = A.val[n+i][n+i] = 1 ;
	    }
	    Mat T = pow(A , k+1) ;
	    for(int i = 1 ; i <= n ; i++){
	    	for(int j = 1 ; j <= n ; j++){
	    		a[i][j] = T.val[n+i][j] ;
	    	}
	    	a[i][i] = (a[i][i] - 1 + Mod) % Mod ;
	    }
	    for(int i = 1 ; i <= n ; i++){
	    	out.print(a[i][1]) ;
	    	for(int j = 2 ; j <= n ; j++)
	    		out.print(" " + a[i][j]) ;
	        out.println() ; 
	    }
		out.flush() ;
	}
}

class InputReader {    
    public BufferedReader reader;    
    public StringTokenizer tokenizer;    
    
    public InputReader(InputStream stream) {    
        reader = new BufferedReader(new InputStreamReader(stream), 32768);    
        tokenizer = new StringTokenizer("");    
    }    
    
    private void eat(String s) {    
        tokenizer = new StringTokenizer(s);    
    }    
    
    public String nextLine() {    
        try {    
            return reader.readLine();    
        } catch (Exception e) {    
            return null;    
        }    
    }    
    
    public boolean hasNext() {    
        while (!tokenizer.hasMoreTokens()) {    
            String s = nextLine();    
            if (s == null)    
                return false;    
            eat(s);    
        }    
        return true;    
    }    
    
    public String next() {    
        hasNext();    
        return tokenizer.nextToken();    
    }    
    
    public int nextInt() {    
        return Integer.parseInt(next());    
    }    
    
    public long nextLong() {    
        return Long.parseLong(next());    
    }    
    
    public double nextDouble() {    
        return Double.parseDouble(next());    
    }    
    
    public BigInteger nextBigInteger() {    
        return new BigInteger(next());    
    }    
    
}    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值