等级五,比较难,坑。
坑之一,开始试了递归和栈都不行。在网上查了算法,首先要写出矩阵的递推公式
一步步递推得到
得到了公式之后,用快速幂方法计算a(k)。如果不是把理论融汇贯通,很难想到这种方法,变为矩阵计算,很妙。路漫漫长啊!
参考的两个网址:
http://www.educity.cn/wenda/369708.html
http://www.cnblogs.com/yan-boy/archive/2012/11/29/2795294.html
最终时间230MS。
坑之二:k为0或者1时要特殊判断,否则会TLE!!!!好坑!!!都木有想到。。。。另外k为0或者1时,输出的a0和a1要模上10000,否则wrong answer
这道题很好,学到了很多东西!
代码:
package Test1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Test13_4_1081 {
/**
* by qr jobdu 1081 2014-8-11
* @throws IOException
* 1.转换为矩阵计算公式 2.二分法计算矩阵 (快速幂计算!!!) http://www.educity.cn/wenda/369708.html
* 【学习理论,一定要搞明白这种理论有什么用处,不然不算学明白了。而遇到实际的问题想不出来时,一定需要及时补充理论知识。】
* 用栈复杂度是n,矩阵是log(n) (表示为二进制)
* 230MS
*/
public static void main(String[] args) throws IOException {
StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
while(st.nextToken()!=StreamTokenizer.TT_EOF){
int a0=(int)st.nval;
st.nextToken();
int a1=(int)st.nval;
st.nextToken();
int p=(int)st.nval;
st.nextToken();
int q=(int)st.nval;
st.nextToken();
int k=(int)st.nval;
if(k==0){ //论坛:用矩阵快速幂模,还要特判k=0,1不然TLE到死。。。。。。。。。。。。。。。
System.out.println(a0%10000); //do not forget "%10000" or wrong answer
continue;
}else if(k==1){
System.out.println(a1%10000);
continue;
}
int matrix[][]=new int[2][2]; //原始矩阵,求该矩阵的k-1次幂
matrix[0][0]=p;
matrix[0][1]=q;
matrix[1][0]=1;
matrix[1][1]=0;
int result[][]=new int[2][2]; //结果矩阵 初始为单位阵,而非全1阵
result[0][0]=1;
result[0][1]=0;
result[1][0]=0;
result[1][1]=1;
int temp[][]=new int[2][2];
//矩阵有k-1次幂,则n=k-1
int n=k-1;
while(n!=0){
if((n&1)!=0){
calculate(result,result,matrix,temp); //result=result*matrix
}
n>>=1;
calculate(matrix,matrix,matrix,temp); //matrix=matrix*matrix
}
System.out.println((result[0][0]*a1+result[0][1]*a0)%10000);
}
}
private static void calculate(int[][] result, int[][] matrix1, //要有一个temp,因为矩阵可能是相同的
int[][] matrix2, int[][] temp) {
temp[0][0]=(matrix1[0][0]*matrix2[0][0]+matrix1[0][1]*matrix2[1][0])%10000;
temp[0][1]=(matrix1[0][0]*matrix2[0][1]+matrix1[0][1]*matrix2[1][1])%10000;
temp[1][0]=(matrix1[1][0]*matrix2[0][0]+matrix1[1][1]*matrix2[1][0])%10000;
temp[1][1]=(matrix1[1][0]*matrix2[0][1]+matrix1[1][1]*matrix2[1][1])%10000;
result[0][0]=temp[0][0];
result[0][1]=temp[0][1];
result[1][0]=temp[1][0];
result[1][1]=temp[1][1];
}
}