首先我们关注同一行的递推式:
F[i][m]=(...(((F[i][1]∗a+b)∗a+b)∗a+b)...)∗a+b =F[i][1]∗am−1+i=0∑m−2bai =F[i][1]∗am−1+ba−1am−1−1则从一行推到下一行:
F[i+1][1]=c∗F[i][m]+d =F[i][1]∗am−1c+bca−1am−1−1+d观察到 F[i+1][1] 的系数为 am−1c 且常数项为 bca−1am−1−1+d ,均为定值,不妨设 k=am−1c 和 t=bca−1am−1−1+d ,则式子变成了如下形式:
F[i+1][1]=F[i][1]∗k+t类似(1)式,有如下推导:
F[n][1]=(...(((F[1][1]∗k+t)∗k+t)∗k+t)...)∗k+t =F[1][1]∗kn−1+i=0∑n−2tki =F[1][1]∗kn−1+tk−1kn−1−1再套用(1)式,得到最终答案(F[n][1]就不代入了):
F[n][m]=F[n][1]∗am−1+ba−1am−1−1其中n,m作为固定的乘方数,除法可用费马小定理换做乘其逆元,可用费马小定理 ap−1≡1(modp) 优化,将高精数对 1e9+6 取模,a=1时也有特判,可是最终提交上去仅有80pts (WA的是3,9,13,17四个点),完全不用担心时间问题(已经快到起飞了),求大佬帮忙看看还有什么漏洞没有...(代码贴在下边)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9,tmod=1e9+7;
ll n[2][200010],nrec[2][200010],n1[2],nrec1[2];
string str[2];
void modd(int id){
int res=n[id][0];
for(int i=res;i>=1;i--){
n[id][i]%=(tmod-1);
if(i>1){
n[id][i-1]+=n[id][i]*mod;
n[id][i]=0;
}
}
return ;
}
void modd1(int id){
int res=nrec[id][0];
for(int i=res;i>=1;i--){
nrec[id][i]%=tmod;
if(i>1){
nrec[id][i-1]+=nrec[id][i]*mod;
nrec[id][i]=0;
}
}
return ;
}
void rd(int s,int r){
ll ans=0,now=1;
for(int i=str[s].length()-1;i>=0;i--){
ans+=now*((ll)str[s][i]-48);
now*=10;
if(now>=mod){
n[r][++n[r][0]]=ans;
ans=0;
now=1;
}
}
if(ans){
n[r][++n[r][0]]=ans;
}
for(int i=0;i<=n[r][0];i++)nrec[r][i]=n[r][i];
modd(r);
modd1(r);
n1[r]=n[r][1]%tmod;
nrec1[r]=nrec[r][1]%tmod;
return ;
}
ll enpow(ll x,ll y){
ll base=x,t=y,ans=1ll;
while(t){
if(t&1){
ans=ans*base%tmod;
}
base=base*base%tmod;
t>>=1;
}
return ans;
}
ll mul(ll x,int id){
return x*nrec1[id]%tmod;
}
int main(){
ll a,b,c,d;
cin>>str[0]>>str[1]>>a>>b>>c>>d;
for(int id=0;id<=1;id++){
for(int i=str[id].length()-1;i>=0;i--){
if(str[id][i]=='0'){
if(i==1){
str[id]=str[id].substr(1,str[id].length()-1);
break;
}
else{
str[id][i]='9';
}
}
else{
str[id][i]-=1;
break;
}
}
}
rd(0,0),rd(1,1);
ll a1=enpow(a,n1[1]),c1=enpow(c,n1[0]);
ll rp;
if(a>1){
rp=b*(a1-1)%tmod*enpow(a-1,tmod-2)%tmod;
}
else rp=mul(b,1);
ll a2=a1*c%tmod,r=(rp*c%tmod+d)%tmod;
ll res=enpow(a2,n1[0]);
ll ans=r;
if(res>1&&a2>1)ans=ans*((res-1)*enpow(a2-1,tmod-2)%tmod)%tmod;
ans=(ans+res)%tmod;
ans=ans*a1%tmod;
ans=ans+rp;
cout<<(ans%tmod+tmod)%tmod<<endl;
return 0;
}