题意很简单 就是对一个数列求和。
题解:如果不考虑符号 每一项都是前一项的 (b/a)倍, 然后考虑到符号的话, 符号k次一循环, 那么 下一个同一符号的位置 就是 这一个位置的 (b/a)^k倍了, 然后我们可以发现这个是一个等比数列, 最后我们对等比数列求和就好了。
注意的就是 (b/a)^k % mod == 1的情况,我们可以将前K个数总和在一起, 在一起求等比的和就好了。
我们可以将公式 cir*(1-q^time) / (1 - q) 其中q = (b/a)^k 转化成 cir * (a1^(time*k) - b^(time*k)) / (a1^(time*k) - b^k * a ^((t-1)*k)) 然后因为要进行mod操作 所以 再转换成 cir * (a1^(time*k) - b^(time*k)) *inv( (a1^(time*k) - b^k * a ^((t-1)*k))) 就好了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c)) 10 #define min3(a,b,c) min(a,min(b,c)) 11 typedef pair<int,int> pll; 12 const int INF = 0x3f3f3f3f; 13 const LL mod = 1e9+9; 14 const int N = 1e5+10; 15 int n, a, b, k; 16 char str[N]; 17 LL qpow(int a, int b){ 18 LL ret = 1; 19 while(b){ 20 if(b&1) ret = (ret*a)%mod; 21 a = (a%mod*a%mod) % mod; 22 b >>= 1; 23 } 24 return ret%mod; 25 } 26 int main(){ 27 scanf("%d%d%d%d",&n,&a,&b,&k); 28 scanf("%s", str); 29 int len = strlen(str); 30 LL ans = 0; 31 LL tmp, cir = 0; 32 for(int i = 0; i < len; i++){ 33 tmp = qpow(a,n-i) * qpow(b,i) % mod; 34 if(str[i] == '+') { 35 cir += tmp; 36 cir %= mod; 37 } 38 else { 39 cir -= tmp; 40 if(cir < 0) cir += mod; 41 cir %= mod; 42 } 43 } 44 int time = (n+1) / len; 45 int lf = n+1 - len*time; 46 int be = len*time; 47 for(int i = 0; be <= n; i++, be++){ 48 tmp = qpow(a,n-be) * qpow(b,be) % mod; 49 if(str[i] == '+') { 50 ans += tmp; 51 ans %= mod; 52 } 53 else { 54 ans -= tmp; 55 if(ans < 0) ans += mod; 56 ans %= mod; 57 } 58 } 59 LL t1 = (qpow(a,len*time) - qpow(b,len*time))%mod; 60 if(t1 < 0) t1 += mod; 61 LL t2 = (qpow(a,len*time) % mod - qpow(b,len)*qpow(a,(time-1)*len)%mod) %mod; 62 if(t2 < 0) t2 += mod; 63 LL t3 = t1 *(qpow(t2,mod-2))% mod; 64 if(t2!=0){ 65 ans = (ans + cir * t3 % mod)%mod; 66 } 67 else { 68 ans = (ans+cir*time%mod)%mod; 69 } 70 printf("%I64d", ans); 71 return 0 ; 72 } 73 /* 74 8 2 3 2 75 ++ 76 */