题意:计算,其中( 0< a, m < 2^15, (a-1)^2< b < a^2, 0 < b, n < 2^31)。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565
——>>这里有个数学知识: (a+√b)n+(a−√b)n 是一个整数,设为Cn,则
因为 (a-1)^2< b < a^2,所以a-1 < √b < a,
所以,0 < a - √b < 1,
所以Sn = Cn % m。
接着构造矩阵,可进行快速幂。
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 2 + 3;
int d, a, b, n, mod;
struct Mar{ //矩阵
int m[maxn][maxn];
Mar(){
memset(m, 0, sizeof(m));
}
};
Mar operator + (Mar A, Mar B){ //矩阵+
Mar ret;
for(int i = 0; i < d; i++)
for(int j = 0; j < d; j++)
ret.m[i][j] = (A.m[i][j] + B.m[i][j]) % mod;
return ret;
}
Mar operator * (Mar A, Mar B){ //矩阵*
Mar ret;
for(int i = 0; i < d; i++)
for(int j = 0; j < d; j++)
for(int k = 0; k < d; k++){
ret.m[i][j] = (ret.m[i][j] + A.m[i][k] * B.m[k][j]) % mod;
}
return ret;
}
Mar pow_mod(Mar M, int N){ //矩阵快速幂
if(N == 1) return M;
Mar x = pow_mod(M, N/2);
x = x * x;
if(N&1) x = x * M;
return x;
}
void solve(){
if(n == 1){
printf("%d\n", 2 * a % mod);
return;
}
d = 2; //矩阵维度
Mar ma;
ma.m[0][0] = 2 * a % mod;
ma.m[0][1] = ((b - a * a) % mod + mod) % mod;
ma.m[1][0] = 1;
ma.m[1][1] = 0;
ma = pow_mod(ma, n-1);
int ret = (ma.m[0][0] * 2 * a % mod + ma.m[0][1] * 2) % mod;
printf("%d\n", ret);
}
int main()
{
while(scanf("%d%d%d%d", &a, &b, &n, &mod) == 4) solve();
return 0;
}
0<a−b√<1Cddn=An+Bn=