对于这道题,我还是先附上大佬的代码,我觉着大佬的比较容易理解!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct mt{
ll a[3][3];
};
mt t(mt a,mt b,ll mod){
mt res;
int i,j,k;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
res.a[i][j]=0;
for(k=0;k<3;k++){
res.a[i][j]+=(a.a[i][k]%mod)*(b.a[k][j]%mod)%mod;
res.a[i][j]%=mod;
}
}
}
return res;
}
mt power(mt a,ll b,ll mod){
mt res;
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
res.a[i][j]=0;
}
}
res.a[0][0]=res.a[1][1]=res.a[2][2]=1;
while(b){
if(b&1)res=t(res,a,mod);
b>>=1;
a=t(a,a,mod);
}
return res;
}
ll feb(ll n,ll mod){
mt temp;
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
temp.a[i][j]=0;
}
}
temp.a[0][1]=temp.a[1][1]=temp.a[1][0]=1;
mt res=power(temp,n-1,mod);
return (res.a[0][0]+res.a[0][1])%mod;
}
ll feb2(ll n,ll mod){
mt temp;
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
temp.a[i][j]=0;
}
}
temp.a[0][0]=temp.a[0][1]=temp.a[0][2]=temp.a[1][0]=temp.a[2][2]=1;
mt res=power(temp,n,mod);
return (res.a[0][2])%mod;
}
ll power(ll a,ll b,ll mod){
ll res=1;
while(b){
if(b&1)res=res*a%mod;
b>>=1;
a=(a%mod)*(a%mod)%mod;
}
return res;
}
int main(){
int m=1e9+7;
int i,j;
ll n,x,y,a,b;
cin>>n>>x>>y>>a>>b;
if(n==1){cout<<x%m;return 0;}
if(n==2){cout<<y%m;return 0;}
if(x%m==0||y%m==0||a%m==0){cout<<0;return 0;}
a=power(a%m,b,m); //这里要注意a对m取模
cout<<power(x,feb(n-2,m-1),m)*power(y,feb(n-1,m-1),m)%m*power(a%m,feb2(n-2,m-1),m)%m<<endl;
}
以下是我的代码!
#include<iostream>
#include<stdio.h>
using namespace std;
#define ll long long
const ll mod= 1e9+7;
struct mat
{
ll l[2][2];
};
mat Powmat(ll a[][2],ll b[][2])
{
mat c;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
c.l[i][j] = 0;
}
}
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k = 0;k<2;k++)
{
c.l[i][j] = (c.l[i][j] + a[i][k] * b[k][j] %(mod - 1))% (mod - 1);//费马小定理
}
}
}
return c;
}
ll Pow(ll a[][2],ll n)
{
mat ans,res;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
ans.l[i][j] = 0;
if(i == j)
ans.l[i][j] = 1;
}
}
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
res.l[i][j]=a[i][j];
}
}
while(n)
{
if(n & 1)
{
ans = Powmat(ans.l,res.l);
}
res = Powmat(res.l,res.l);
n = n >> 1;
}
return ans.l[0][0];
}
ll poww(ll a,ll b)
{
if(a==0) return 0;
ll ans = 1;
ll res = a;
while(b)
{
if(b & 1)
{
ans = ans % mod * res % mod ;
}
res = res % mod * res % mod ;
b = b >> 1;
}
return ans;
}
int main()
{
ll n,x,y,a,b;
ll e[2][2];
cin>> n>> x>> y >>a >> b;
x = x % mod; y = y % mod; a = a % mod;
if(x == 0||y == 0||a == 0)
{
cout <<0;return 0;
}
if(n == 1)
{
cout<< x;
return 0;
}
if( n == 2)
{
cout << y;
return 0;
}
ll t = poww(a,b);
e[0][0] = 1; e[0][1]= 1;
e[1][0]= 1; e[1][1]= 0;
ll p = Pow(e,n-3) % mod;
ll q = Pow(e,n-2) % mod;
ll j = (p + q -1);
printf("%lld",poww(x,p) % mod * poww(y,q) % mod * poww(t,j) % mod);
return 0;
}
我的一直都是90.91%,到最后发现是%mod取的太多了,以后吸取教训,还有矩阵快速幂的模板也需要自己写一份了!
链接:https://ac.nowcoder.com/acm/contest/3002/F
来源:牛客网