hdu2604矩阵快速幂

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;

public class Main {

        public static void main(String[] args) throws IOException{
                StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in)); 
                InputReader in = new InputReader(System.in)  ;
                PrintWriter out = new PrintWriter(System.out) ;

                while(cin.nextToken() != cin.TT_EOF){
                     int n = (int)cin.nval ;
                     cin.nextToken() ;  int mod = (int) cin.nval ;

                     out.println( new Task().solve(n , mod) ) ;      

                     out.flush() ;
                }

                out.flush() ;
        }

}

class  Task{

       public  long  solve(int n , int mod){
               if(n == 1) return 2 % mod ;
               if(n == 2) return 4 % mod ;
               if(n == 3) return 6 % mod ;
               if(n == 4) return 9 % mod ;

               Mat A = new Mat(new int[][]{{1,0,1,1}
                                           ,{1,0,0,0}
                                           ,{0,1,0,0}
                                           ,{0,0,1,0}} ) ;
               A = A.Pow(n-4, mod) ;
               long ans = 0 ;
               ans = (ans + A.a[0][0] * 9) % mod ;
               ans = (ans + A.a[0][1] * 6) % mod ;
               ans = (ans + A.a[0][2] * 4) % mod ;
               ans = (ans + A.a[0][3] * 2) % mod ;

               return ans ;
       } 
}


class  Mat{
       int [][]a ;


       public  Mat(int[][] c){
               a = new int[4][4] ;
               for(int i = 0 ; i < 4 ; i++)
                    for(int j = 0 ; j < 4 ; j++) a[i][j] = c[i][j] ;
       }


       public  Mat(){
               a = new int[4][4] ;
               for(int i = 0 ; i < 4 ; i++) Arrays.fill(a[i], 0) ;
       }

       public  Mat(int one){
               a = new int[4][4] ;
               for(int i = 0 ; i < 4 ; i++){
                   Arrays.fill(a[i], 0) ;
                   a[i][i] = 1 ;
               }
       }

       Mat  mult(Mat other , int mod){
            Mat s  = new Mat() ;
            for(int i = 0 ; i < 4 ; i++){
                 for(int j = 0 ; j < 4 ; j++){
                       for(int k = 0 ; k < 4 ; k++){
                           s.a[i][j] += a[i][k] * other.a[k][j]  ;
                           if(s.a[i][j] >= mod) s.a[i][j] %= mod ;
                       }
                 }
            }
            return s ;
       }

       Mat Pow(int y , int mod){
           Mat s = new Mat(1) ;
           Mat x = this ;

           for(; y > 0 ; y >>= 1){
               if((y & 1) == 1)  s = s.mult(x, mod) ;
               x = x.mult(x, mod) ;
           }

           return s ;
       }
}




class InputReader{
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream){
           reader = new BufferedReader(new InputStreamReader(stream), 32768);
           tokenizer = null;
    }

    public String next(){
        while(tokenizer == null || !tokenizer.hasMoreTokens()){
            try{
                tokenizer = new StringTokenizer(reader.readLine());
            }catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值