1.国庆的牛客没有打,于是乎坐在车上觉得还挺无聊,就看了看题目
其中有一个这样的签到题,矩阵快速幂加了一点点的限制,让n十分大,其实这是快速幂的另一种使用,叫做十进制快速幂。牛客多校dreamoon出过一次。
原理也很简单了,思考一下快速幂其实就是把这个数搞成二进制,然后按位考虑复杂度就是这个数二进制位数的个数,那么对于一个长度1e6的十进制数,转成二进制不会超过3e6,所以我们做类似的操作,先在每一位上十进制快速幂,然后十进制的每一位二进制快速幂。(当存个板子了,其实也没啥好存的,就几行代码)
#include<bits/stdc++.h>
using namespace std;
int n, p=7;
struct mat {
static const int N = 2;
int a[2][2];
mat() {
a[0][0] = a[1][1] = 1;
a[0][1] = a[1][0] = 0;
}
mat operator*(const mat& m)const
{
mat res;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
res.a[i][j] = 0;
for (int k = 0; k < 2; k++)
{
res.a[i][j] = (res.a[i][j] + 1ll * a[i][k] * m.a[k][j] % p) % p;
}
}
}
return res;
}
};
mat qpow(mat a, int t)
{
mat res;
while (t)
{
if (t & 1)res = res * a;
a = a * a;
t >>= 1;
}
return res;
}
mat qpow(mat a, char s[]) {
mat res;
for (int i = n-1; i >= 0; --i)
{
if (s[i] != '0') res = res * qpow(a, s[i] - '0');
a = qpow(a, 10);
}
return res;
}
const int N = 1e6 + 10;
char s[N];
int main()
{
scanf("%s", &s);
n = strlen(s);
mat m;
scanf("%d%d%d%d", &m.a[0][0], &m.a[0][1], &m.a[1][0], &m.a[1][1]);
mat res = qpow(m, s);
cout << res.a[0][0] << " " << res.a[0][1] <<endl;
cout<< res.a[1][0] << " " << res.a[1][1] << endl;
return 0;
}