小X的暑假作业
问题描述
小X的作业是老师给他布置的,题目很简单,求出第N个斐波那契数 mod P的值。小X怎么想也想也想不出来,只好求助于你了。
输入格式
第一行为数据组数T。
第二行开始,以下T行,每行为老师给小X布置的作业中的N和P。
输出格式
包含T行,每行是一个作业的答案。
样例输入
3
7 3
1000000 89
987654321 30000
样例输出
0
55
19111
数据规模和约定
对于50%的数据,T<=100,N<=10000。
对于100%的数据,T<=10000,N<=1000000000,P<=30000。
斐波那契数的第0个是1。
public class 小X的暑假作业 { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc=new Scanner(System.in); int T=sc.nextInt(); while(T-->0){ long n=sc.nextLong(); int p=sc.nextInt(); long q[][]={{0,1},{1,1}};//下标从0开始 long a[][]={{1,1}}; long res[][]; long end[][]; res=matrixpower(q,n-1,p); //res为q矩阵的n-1次方 end=mutiply(a,res,p); //mutiply实现两个矩阵相乘 System.out.println(end[0][0]%p); } } private static long[][] matrixpower(long[][] q, long n,int p) { //实现矩阵q的n次 long[][] res=new long[2][2]; //把res矩阵初始化为单位矩阵 for(int i=0;i<q.length;i++){ res[i][i]=1; } //快速幂实现 while(n>0){ if((n&1)==1){ res = mutiply(res, q,p); } q =mutiply(q, q,p);//乘方一直翻倍 n>>=1; } return res; } private static long[][] mutiply(long[][] a, long[][] b,int p) { long[][] res=new long[a.length][b.length]; for(int i=0;i<a.length;i++){ for(int j=0;j<b.length;j++){ long temp=0; for(int k=0;k<a[0].length;k++){ temp= ((temp+(a[i][k]*b[k][j])%p))%p; } res[i][j]=temp; } } return res; } }