/*求f(ki+b) 0<=i<n
求斐波那契构造矩阵A[2][2]={1,1,1,0} f(n)=A^n
所以根据题意有f(b)=A^b 注意 f(k+b)=A^(k+b)=A^k*A^b
f(k+b)=A^(k+b)
……
f((n-1)k+b)=A^((n-1)k+b)
s=f(b)+f(k+b)+f(2k+b)……+f((n-1)k+b)
s=A^b+A^(k+b)……A^((n-1)k+b)
=A^b(I+A^k+A^2k+……+A^(n-1)k)
把A^k看成一个整体,二分求解。
*/
http://acm.hdu.edu.cn/showproblem.php?pid=1588
#include<iostream>
#include<stdio.h>
#define ll long long
using namespace std;
struct matrix
{
ll mat[2][2];
};
const int n=2;
int k,b,nn,m;
matrix unit,qiqi;
matrix mul(matrix a,matrix b)
{
matrix c;
int i,j,k;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
c.mat[i][j]=0;
for(k=0;k<n;k++)
c.mat[i][j]=(a.mat[i][k]*b.mat[k][j]+c.mat[i][j])%m;
c.mat[i][j]%=m;
}
return c;
}
matrix power(matrix a,int x)
{
if(x==1) return a;
matrix b=power(a,x/2);
b=mul(b,b);
if(x%2) b=mul(b,a);
return b;
}
matrix add(matrix a,matrix b)
{
matrix c;
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
c.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%m;
return c;
}
matrix sum(matrix a,int x) //A+A^2+...A^x
{
if(x==1) return a;
matrix temp=sum(a,x>>1);
if(x&1)
{
matrix tmp=power(a,(x>>1)+1); //比如 x=7 tmp=A^4 temp=(A^1+A^2+A^3)
return add(add(mul(temp,tmp),temp),tmp);//A^4(A^1+A^2+A^3)+A^4+(A^1+A^2+A^3)
}
else
{
matrix tmp=power(a,(x>>1));
return add(mul(tmp,temp),temp);
}
}
int main()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
unit.mat[i][j]=(i==j);
qiqi.mat[0][0]=qiqi.mat[0][1]=qiqi.mat[1][0]=1;
qiqi.mat[1][1]=0;
while(scanf("%d%d%d%d",&k,&b,&nn,&m)!=EOF)
{
matrix res;
res=power(qiqi,k);//A^k
res=sum(res,nn-1);//A+A^2+...+A^nn
res=add(res,unit);
matrix ans=power(qiqi,b);
res=mul(ans,res);
printf("%I64d\n",res.mat[1][0]);
}
return 0;
}