题意
已知 a、b、c、d、n、m a 、 b 、 c 、 d 、 n 、 m ,求 F(n,m) F ( n , m )
题解
我们先来化简这个式子
通过第一个式子,我们可以得到 f(i,m)=am−1f(i,1)+(am−2+am−3+⋯a+1)b f ( i , m ) = a m − 1 f ( i , 1 ) + ( a m − 2 + a m − 3 + ⋯ a + 1 ) b
重新考虑答案
简化一波…令 p=(am−2+am−3+⋯+a+1)b p = ( a m − 2 + a m − 3 + ⋯ + a + 1 ) b , x=am−1c x = a m − 1 c , y=am−1d+p y = a m − 1 d + p , q=(xn−2+xn−3+⋯+x+1)y q = ( x n − 2 + x n − 3 + ⋯ + x + 1 ) y (后面会有用)
那么,原式就等于
显然 p、q p 、 q 可以用等比数列求出(等比为 1 1 的时候另行讨论)
然而 就不能直接算了
通过费马小定理 a(p−1)≡1 a ( p − 1 ) ≡ 1 (mod ( m o d p) p ) , 所以 ap=a(pmod(k−1))(modk) a p = a ( p m o d ( k − 1 ) ) ( m o d k )
代码
#include <cstdio>
#include <cstring>
#define mod 1000000007
#define N 1000005
#define ll long long
char str1[N];
int n,m,n1,m1,a,b,c,d;
int qpow(int x,int y){
int t=1;
while(y){
if(y&1) t=(ll)t*x%mod;
x=(ll)x*x%mod;y>>=1;
}return t;
}
int main(){
freopen("a.in","r",stdin);
scanf("%s",str1+1);
n=0,n1=0;int nn=strlen(str1+1);
for(int i=1;i<=nn;i++) n=((ll)n*10+str1[i]-'0')%(mod-1),n1=((ll)n1*10+str1[i]-'0')%mod;
n=(n-1+mod-1)%(mod-1);n1=(n1-1+mod)%mod;
scanf("%s",str1+1);
m=0,m1=0;nn=strlen(str1+1);
for(int i=1;i<=nn;i++) m=((ll)m*10+str1[i]-'0')%(mod-1),m1=((ll)m1*10+str1[i]-'0')%mod;
m=(m-1+mod-1)%(mod-1);m1=(m1-1+mod)%mod;
scanf("%d%d%d%d",&a,&b,&c,&d);
int am=qpow(a,m),x=(ll)am*c%mod,p;
if(a==1) p=(ll)m1*b%mod;
else p=(ll)b*(am-1+mod)%mod*qpow(a-1,mod-2)%mod;
int xn=qpow(x,n),y=((ll)am*d%mod+p)%mod,q;
if(x==1) q=(ll)n1*y%mod;
else q=(ll)y*(xn-1+mod)%mod*qpow(x-1,mod-2)%mod;
printf("%d\n",(((ll)am*xn%mod+(ll)xn*p%mod)%mod+q)%mod);
return 0;
}