da
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
struct matrix
{
__int64 mat[4][4];
};
matrix matmul(matrix a,matrix b,int n,int m)
{
int i,j,k;
matrix c;
memset(c.mat,0,sizeof(c.mat));
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
for(k=0; k<n; k++)
{
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
c.mat[i][j]%=m;
}
}
}
return c;
}
matrix matpow(matrix a,int k,int n,int m)
{
matrix b;
int i;
memset(b.mat,0,sizeof(b.mat));
for(i=0; i<n; i++) b.mat[i][i]=1;
while(k)
{
if(k&1) b=matmul(a,b,n,m);
a=matmul(a,a,n,m);
k>>=1;
}
return b;
}
int main()
{
int x,y,k,m;
while(cin>>x>>y>>k>>m)
{
__int64 aa[123];
matrix a,b,ans;
memset(a.mat,0,sizeof(a.mat));
memset(b.mat,0,sizeof(b.mat));
aa[0]=1%m;
aa[1]=(__int64)ceil(x+sqrt(y*1.0))+m; //ceil()为向上取整函数
aa[1]%=m;
aa[2]=(__int64)ceil((x+sqrt(y*1.0))*(x+sqrt(y*1.0)))+m;
aa[2]%=m;
if(k<3)
{
printf("%I64d\n",aa[k]);
continue;
}
a.mat[0][0]=aa[2];a.mat[0][1]=aa[1]; //构造矩阵
b.mat[0][0]=2*x;b.mat[0][1]=1;
b.mat[1][0]=y-x*x;
ans=matmul(a,matpow(b,k-2,2,m),2,m);
printf("%I64d\n",(ans.mat[0][0]+m)%m); //注意负数的情况
}
}