🔗https://www.tzcoder.cn/acmhome/problemdetail.do?method=showdetail&id=4954
解析
首先我们需要输入N与M,然而因为数据过于大,我们就需要用字符串读入,通过取模后完成数据的输入
ll qz(string s,int x)
{
ll aa=0;
for (int i=0;i<s.size();i++)
{
aa=(aa*10+(s[i]-'0'))%x;
}
return aa;
}
这道题等价于求 (A^(m−1)*B)^(n−1)*A^(m−1)。
可以直接用高精度的矩阵快速幂。
不难发现在计算过程中矩阵一定是 B[0][0]=a; B[1][0]=b; B[0][1]=0; B[1][1]=1;的形式。
所以现在问题转化为了计算型为B[0][0]=a; B[1][0]=b; B[0][1]=0; B[1][1]=1;的矩阵快速幂。
矩阵的快速幂又可以体现成矩阵乘再加上快速幂
固可以推出
矩阵快速幂
void cc(ll a[2][2],ll b[2][2])
{
ll res[2][2];
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
res[i][j]=0;
for(int k=0;k<2;k++)
res[i][j]=(res[i][j]+a[i][k]*b[k][j])%MOD;
}
}
for (int i=0;i<2;i++)
{
for (int j=0;j<2;j++)
a[i][j]=res[i][j];
}
}
while(m)
{
if (m&1)
cc(D,B);
cc(B,B);
m>>=1;
}
注意
当这里的a或c等于一时要加入特判,
a^b % p 在b远大于a的时候可以先用b = b%(p-1),
不过在a为1的时候还是%p;
if (a==1)
n=qz(ns,MOD);
else
n=qz(ns,MOD-1);
if (c==1)
m=qz(ms,MOD);
else
m=qz(ms,MOD-1);
这样就可以写出来啦
#include <iostream>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <set>
#include <cstring>
#include <map>
#include <stdio.h>
using namespace std;
const int MOD=1000000007;
typedef long long int ll;
string ns,ms;
ll A[2][2],B[2][2],C[2][2],D[2][2],qq[2][2];
ll qz(string s,int x)
{
ll aa=0;
for (int i=0;i<s.size();i++)
{
aa=(aa*10+(s[i]-'0'))%x;
}
return aa;
}
void cc(ll a[2][2],ll b[2][2])
{
ll res[2][2];
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
res[i][j]=0;
for(int k=0;k<2;k++)
res[i][j]=(res[i][j]+a[i][k]*b[k][j])%MOD;
}
}
for (int i=0;i<2;i++)
{
for (int j=0;j<2;j++)
a[i][j]=res[i][j];
}
}
ll n,m,a,b,c,d;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >> ns >> ms;
cin >> a >> b >> c >> d;
if (a==1)
n=qz(ns,MOD);
else
n=qz(ns,MOD-1);
if (c==1)
m=qz(ms,MOD);
else
m=qz(ms,MOD-1);
m--;
n--;
A[0][0]=1;
A[0][1]=1;
A[1][1]=0;
A[1][0]=0;
B[0][0]=a;
B[1][0]=b;
B[0][1]=0;
B[1][1]=1;
C[0][0]=c;
C[1][0]=d;
C[0][1]=0;
C[1][1]=1;
D[0][0]=D[1][1]=1;
D[0][1]=D[1][0]=0;
while(m)
{
if (m&1)
cc(D,B);
cc(B,B);
m>>=1;
}
qq[0][0]=D[0][0];
qq[0][1]=D[0][1];
qq[1][0]=D[1][0];
qq[1][1]=D[1][1];
cc(D,C);
while(n)
{
if(n&1)
cc(A,D);
cc(D,D);
n>>=1;
}
cc(A,qq);
cout << A[0][0];
return 0;
}