題目大意:ios
看一下樣例就明白了spa
基本思路:code
題目中明確提到k爲一個週期,稍做思考,把k項看做一項,而後發現這是個等比數列,q=(b/a)^k,blog
而後重點就是怎樣處理等比數列求和表達式中的除法,這個時候就要用到逆元,由於1e9+9是素數,ci
因此直接用費馬小定理求逆元就行了,說到這個,能夠學一下盧卡斯定理,這個比較有用處,而後須要注意string
兩點:it
1)快速冪a的每次乘方里面都要%mod,這個究竟是爲何我也不知道,難道不是隻在外面取模一次就行了嗎io
2)最後判斷條件是t2是否等於0,而不是a是否等於b,難道不是等價的嗎?爲何會這樣?class
代碼以下:stream
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<string> #include<algorithm> #include<queue> #include<vector> using namespace std; typedef long long ll; typedef long long LL; typedef pair<int,int> pii; const int inf = 0x3f3f3f3f; const int maxn = 100000+10; const ll mod = 1e9+9; char s[maxn]; ll qpow(int a,int b){ ll res=1; while(b){ if(b&1) res=(res*a)%mod; a=(a%mod*a%mod)%mod; b>>=1; } return res%mod; } int main(){ int n,a,b,k; scanf("%d%d%d%d",&n,&a,&b,&k); scanf("%s", s); int len = strlen(s); LL ans = 0; LL tmp, cir = 0; for(int i = 0; i < len; i++){ tmp = qpow(a,n-i) * qpow(b,i) % mod; if(s[i] == '+') { cir += tmp; cir %= mod; } else { cir -= tmp; if(cir < 0) cir += mod; cir %= mod; } } int time = (n+1) / len; int lf = n+1 - len*time; int be = len*time; for(int i = 0; be <= n; i++, be++){ tmp = qpow(a,n-be) * qpow(b,be) % mod; if(s[i] == '+') { ans += tmp; ans %= mod; } else { ans -= tmp; if(ans < 0) ans += mod; ans %= mod; } } ll t1=(qpow(a,len*time)-qpow(b,len*time))%mod; if(t1<0) t1+=mod; ll t2=(qpow(a,k*time)-(qpow(a,k*(time-1))*qpow(b,k)%mod))%mod; if(t2<0) t2+=mod; ll t3=t1*qpow(t2,mod-2)%mod; if(t2==0){ printf("%I64d\n",(ans+cir*time%mod)%mod); }else{ printf("%I64d\n",(ans+cir*t3%mod)%mod); } return 0; }