题目链接:
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1658
题意:
给一个方程Y = (AX + BY)%P,X = Y。求n次运算后得到的Y值。
思路:
矩阵快速幂第一题。
源码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
typedef long long LL;
LL block[2][2];///存储矩阵
LL tblock[2][2];
LL x,y;
void mul1(LL p)
{
for(int i=0; i<2; i++){
for(int j=0; j<2; j++){
tblock[i][j] = 0;
for(int k=0; k<2; k++)
tblock[i][j] = (tblock[i][j] + block[i][k] * block[k][j]) % p;///1 1 = 10 * 0 1 + 11 * 11
}
}
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
block[i][j] = tblock[i][j];
}
void mul2(LL p)
{
LL ans = 0;
LL t1,t2;
// printf("before x = %lld, y = %lld\n",x,y);
// printf("block\n");
// for(int i=0; i<2; i++){
// for(int j=0; j<2; j++)
// printf("%lld ",block[i][j]);
// printf("\n");
// }
t2 = block[0][1] * x % p + block[1][1] * y % p;
t1 = block[0][0] * x % p + block[1][0] * y % p;
// printf("t1 = %lld, t2 = %lld\n",t1,t2);
x = t1 % p;
y = t2 % p;
// printf("after x = %lld, y = %lld\n",x,y);
}
int main()
{
int t;
scanf("%d",&t);
for(int cas = 1; cas <= t; cas++){
LL a,b,p,n;
scanf("%lld %lld %lld %lld %lld %lld",&x,&y,&a,&b,&p,&n);
// printf("n = %d\n",n);
block[0][0] = 0;
block[0][1] = a;
block[1][0] = 1;
block[1][1] = b;
LL ans = 0;
// printf("\nblock\n");
// for(int i=0; i<2; i++){
// for(int j=0; j<2; j++)
// printf("%d ",block[i][j]);
// printf("\n");
// }
while(n){
if(n & 1){
mul2(p);
}
mul1(p);
// printf("\nblock\n");
// for(int i=0; i<2; i++){
// for(int j=0; j<2; j++)
// printf("%d ",block[i][j]);
// printf("\n");
// }
// printf("n = %d\n",n);
n = n >> 1;
}
printf("Case #%d: %lld\n",cas,y);
}
return 0;
}
/*
0 1 * 0 1 = 1 1
1 1 1 1 1 2
*/