For many recursive topics, because the data range is too large direct loop write will explode, then the first thought is the matrix optimization, the recursive conversion to 01 matrix by fast Power optimization.
For example, the simplest Fibonacci gschirnwirt, if n is very large, the cyclic recursion is certainly not appropriate, then consider the following formula (F[n],f[n-1]) = (f[n-1],f[n-2]) *a; Here A is a 01 matrix, at this time the a={1,1,1,0} 2*2 Matrix, imagine f[3] = a n-2 Power * (f[2],f[1]); The recursive formula transformation matrix, such as the Fibonacci Gschirnwirt, is simple, by the way, with the code of the fast power of the POJ3070 Fibonacci Gschirnwirt to the matrix.
#include <cstdio>#include<cstring>#include<iostream>#defineMOD 10000using namespacestd;structmac{intfrob[2][2];} Pri,unit;mac Power (Mac X,mac y) {mac temp; for(intI=0;i<2; i++) { for(intj=0;j<2; j + +) {Temp.frob[i][j]=0; for(intk=0;k<2; k++) {Temp.frob[i][j]= (Temp.frob[i][j]+x.frob[i][k]*y.frob[k][j])%MOD; } } } returntemp;}voidEachother (intN) {pri.frob[0][0]=pri.frob[0][1]=pri.frob[1][0]=1; pri.frob[1][1]=unit.frob[0][1]=unit.frob[1][0]=0; unit.frob[0][0]=unit.frob[1][1]=1; while(n) {if(n&1) {Unit=Power (UNIT,PRI); } pri=Power (PRI,PRI); N>>=1; } printf ("%d\n", unit.frob[0][1]);}intMain () {intN; while(SCANF ("%d", &n)! =EOF) { if(n==-1) Break; if(n==0) {printf ("0\n"); Continue; } if(n==1|| n==2) {printf ("1\n"); Continue; } eachother (n); } return 0;}
Simple Recursive formula transformation matrix solution