数列A的满足An=x*An-1+y,给出n,A0,x,y,求模100000007后的结果。
输入格式
第1行包含4个整数n,A0,x,y
输出格式
只有1行包含1个整数,An模100000007后的结果。
样例输入
样例输入1:
1000 333 1 233
样例输入2:
100 2 3 3
样例输出
样例输出1:
233333
样例输出2:
63011400
提示
对于10%的数据,x=0。
对于另10%的数据,x=1。
对于另10%的数据,y=0。
对于另20%的数据,n<=10000000。
对于另30%的数据,y%(x-1)=0。
输入格式
第1行包含4个整数n,A0,x,y
输出格式
只有1行包含1个整数,An模100000007后的结果。
样例输入
样例输入1:
1000 333 1 233
样例输入2:
100 2 3 3
样例输出
样例输出1:
233333
样例输出2:
63011400
提示
对于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范围内。
分析:
注意一定要仔细阅读提示,里面包含了许多特殊的情况!!!
(1) x==0 该数列为等差数列。
(2)y==0 该数列为等比数列。
(3)n==0 直接输出a0‘。
(4)一般情况:由数学知识可知 {a[n]+y/(x-1)}是公比为x,首项为a0的等比数列。
于是 a[n]+y/(x-1)= {a[1]+y/(x-1) } * (x^(n-1))
==> a[n]* (x-1) = (a[1] *(x-1)+y) * (x^(n-1))-y
右边容易用快速幂算出,还需要求x-1的乘法逆元。
注意:这类题计算过程中能模就模,以避免溢出。
代码如下:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=100000007;
LL n,a1,x,y;
LL pow_mod(LL a,LL b,LL t){
LL ans=1;
for(a%=t;b;a=a*a%t,b>>=1)
if(b&1)ans=ans*a%t;
return ans;
}
int main(){
LL i,j,p,t,ans;
cin>>n>>a1>>x>>y;
n++;
if(n==1){
cout<<a1%mod; return 0;
}
else if(x==1){
cout<<(a1+(n-1)*y)%mod; return 0;
}
else if(y==0){
cout<<a1*pow_mod(x,n-1,mod)%mod; return 0;
}
ans=pow_mod(x,n-1,mod);
p=pow_mod(x-1,mod-2,mod);
t=(a1*(x-1)+y)%mod;
ans=(ans*t%mod-y+mod)%mod*p%mod;
cout<<(ans+mod)%mod;
return 0;
}