给出 n,a,b,k n , a , b , k .
输入 k k 个数 全是 1 1 或 −1 − 1 的序列 S S .
求 ∑sian−ibi ∑ s i a n − i b i 对 1e9+9 1 e 9 + 9 取模的结果。
数据范围 n,a,b<=109 n , a , b <= 10 9 k<=105 k <= 10 5
直接暴力把表打出来 发现每个数构成了一个等比数列。观察发现公比为 (b/a) ( b / a )
因为是存在循环节的 所以每个循环节之间也是等比数列。循环节的和的公比为 (b/a)k ( b / a ) k
先暴力算出首项
等比数列求和算出中间的 sum=a1∗(1−bin)/(1−bi) s u m = a 1 ∗ ( 1 − b i n ) / ( 1 − b i )
暴力算后面多出的部分
复杂度 O(klogn) O ( k l o g n )
#include
using namespace std;
const int MOD=1e9+9;
const int MAXN=1e5+5;
typedef long long ll;
char qwq[MAXN];
int s[MAXN],n,a,b,k;
ll qpow(ll a,ll b){
ll ans=1,base=a;
while(b){
if(b&1)(ans*=base)%=MOD;
(base*=base)%=MOD;
b>>=1;
}
return ans;
}
int main(){
scanf("%d%d%d%d",&n,&a,&b,&k);
ll bi=qpow(b,k)*qpow(qpow(a,k),MOD-2)%MOD;
scanf("%s",qwq);
for(int i=1;i<=k;i++){
s[i]=qwq[i-1]=='+'?1:-1;
}
if(bi==1){
ll base=0,ans=0,tmp=0;
for(int i=0;is[i+1]*qpow(a,n-i)*qpow(b,i);
base%=MOD;base+=MOD;base%=MOD;
}
ans=base;
int lun=(n+1)/k,qidian=lun*k,cnt=0;
ans=ans*lun;ans%=MOD;ans+=MOD;ans%=MOD;
for(int i=qidian;i<=n;i++){
ans+=s[++cnt]*base;
ans%=MOD;ans+=MOD;ans%=MOD;
}
ans+=MOD;ans%=MOD;
cout<return 0;
}
else {
int lun=(n+1)/k,qidian=lun*k,cnt=0;
cnt=n-qidian+1;
ll ans=0;
for(int i=0;is[i+1]*qpow(a,n-i)*qpow(b,i);
ans%=MOD;ans+=MOD;ans%=MOD;
}
//ll sum=ans*(1-qpow())
ll sum=ans*(1-qpow(bi,lun))%MOD*qpow(1-bi,MOD-2)%MOD;
sum+=MOD;sum%=MOD;
for(int i=1;i<=cnt;i++){
sum+=s[i+1]*qpow(a,n-qidian)*qpow(b,qidian);
sum%=MOD;sum+=MOD;sum%=MOD;
qidian++;
}
cout<return 0;
}
/*
621922027 16665164 173157 4676
*/
// (b/a)^k +