hdoj1588(2)


void
getSum(){
n--;
int
cnt=
0;
bool
dig[
10];
while
(n){
dig[cnt++]=n&
1;
n>>=
1;
}

//S=0;C=E
memset(S,0,sizeof(S));
memset(C,
0,sizeof(C));
C[
1][1]=C[2][2]=1;
while
(cnt--){

//T=S*(C+E)
D[1][1]=C[1][1]+1;D[1][2]=C[1][2];//D=C+E
D[2][1]=C[2][1];D[2][2]=C[2][2]+1;
memset(T,
0,sizeof(T));
for
(int i=
1;i<=2;i++)//T=S*D
for(int j=1;j<=2;j++)
for
(int k=
1;k<=2;k++){
T[i][j]+=S[i][k]*D[k][j];
T[i][j]%=M;
}

//D=C^2
memset(D,0,sizeof(D));
for
(int i=
1;i<=2;i++)
for
(int j=
1;j<=2;j++)
for
(int k=
1;k<=2;k++){
D[i][j]+=C[i][k]*C[k][j];
D[i][j]%=M;
}

if
(dig[cnt]){

//C=D*A=C^2*A
memset(C,0,sizeof(C));
for
(int i=
1;i<=2;i++)
for
(int j=
1;j<=2;j++)
for
(int k=
1;k<=2;k++){
C[i][j]+=D[i][k]*K[k][j];
C[i][j]%=M;
}

//S=T+C
S[1][1]=(T[1][1]+C[1][1])%M;
S[
1][2]=(T[1][2]+C[1][2])%M;
S[
2][1]=(T[2][1]+C[2][1])%M;
S[
2][2]=(T[2][2]+C[2][2])%M;
}

else
{

//C=D;
C[1][1]=D[1][1];C[1][2]=D[1][2];
C[
2][1]=D[2][1];C[2][2]=D[2][2];
//S=T;
S[1][1]=T[1][1];S[1][2]=T[1][2];
S[
2][1]=T[2][1];S[2][2]=T[2][2];
}
}

S[
1][1]++;
S[
2][2]++;
}


void
getAns(){

//T=S*B
memset(T,0,sizeof(T));
for
(int i=
1;i<=2;i++)
for
(int j=
1;j<=2;j++)
for
(int k=
1;k<=2;k++){
T[i][j]+=S[i][k]*B[k][j];
T[i][j]%=M;
}

//ans
ans=T[1][2];
}

int
main(){

//freopen("input","r",stdin);
A[1][1]=0;A[1][2]=A[2][1]=A[2][2]=1;
while
(scanf(
"%d%d%d%d",&k,&b,&n,&M)!=EOF){
//求B=A^b
getB();
//求K=A^k
getK();
//求K^0+K^1+..+K^(n-1)
getSum();
//求ans
getAns();
printf(
"%lld\n",ans);
}
}


posted @ 2010-08-15 18:07  open source  阅读(106)  评论(0编辑  收藏