数列
Description
数列A满足An=x*An-1+y,给出n,A0,x,y,求模100000007后的结果
Input
第1行包含4个整数n,A0,x,y
Output
只有1行包含1个整数,An模100000007后的结果。
Sample Input
样例输入1:
1000 333 1 233
样例输入2:
100 2 3 3
Sample Output
样例输出1:
233333
样例输出2:
63011400
Hint
对于10%的数据,x=0。
对于另10%的数据,x=1。
对于另10%的数据,y=0。
对于另20%的数据,n<=10000000。
对于另30%的数据,y%(x-1)=0。
对于100%的数据,n在long long范围内,A0,x,y在int范围内。
对数论的基础要求比较高的题
分析了数列我们应该想到:
第一:对于x=0的情况,直接输出答案,如果n=0输出a0,否则输出y。
第二:对于x=1的情况,其实就是等差数列,直接求通项公式。
第三:对于y=0的情况,其实就是等比数列,直接求通项公式,用二分快速幂算答案。
第四:对于n<=10000000的情况,直接逐项递推。
第五:前面用了这么多通项公式,其实就是暗示你直接求通项公式。对于y%(x-1)=0的情况,直接求出通项公式再用
二分快速幂算答案。
第六:对于一般的情况。
#include<iostream>
#define LL long long
using namespace std;
LL n,a,x,y,ans;
const int mod=100000007;
LL doub(LL x,LL y){
LL ans=1LL;
x%=mod;
while(y){
if(y&1)ans=ans*x%mod;
y>>=1;
x=x*x%mod;
}
return ans;
}
void adg(LL i,LL j,LL &x,LL &y){
if(j==0){x=1LL,y=0LL;return;}
adg(j,i%j,y,x);
y-=i/j*x;
return;
}
int main(){
LL xx,yy;
cin>>n>>a>>x>>y;
a%=mod;
x%=mod;
y%=mod;
if(x!=1&&x!=0){
a=(((x-1)*a%mod+y)%mod*doub(x,n%(mod-1))%mod-y+mod)%mod;
adg(x-1,mod,xx,yy);
if(x<0)x+=mod;
ans=a*xx%mod;
}
else if(x==1)ans=(a+n*y)%mod;
else if(x==0)
if(n==0)ans=a;
else ans=y;
cout<<(ans+mod)%mod;
}