题目大意: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; }