题目链接:点击打开链接
题目大意:给一个序列只含'-'和 '+',长度为K,扩展成长度N+1(k为循环节长度),一个算式,(a +b)^n,去掉组合数,该位置的符号如果是+则为正,反之为负,求结果%mod的值(一定为正)。(这写的什么东西啊!)
解题思路:先求出前k个加起来的ans,这时候可以想到用等比数列来求后面的, 公比q = (b ^k)/(a ^ k),由等比数列的前n项和公式得到最终答案就是ans * (q ^ times - 1) * (q - 1) 的逆元
注意特判一下q == 1的时候的情况
代码:
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<string> #include<iomanip> #include<vector> #include<map> #include<set> #define FAST ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) typedef long long ll; const int maxn = (int)1e5 + 5; const ll mod = (int)1e9 + 9; using namespace std; ll quickpow(ll x, ll y){ ll res = 1; while(y){ if(y & 1) res = (res * x) % mod; y >>= 1; x = (x * x) % mod; } return res % mod; } char s[maxn]; int main() { FAST; int n, a, b, k; scanf("%d %d %d %d", &n, &a, &b, &k); ll times = (n + 1) / k; scanf("%s", s); ll ans = 0; for(int i = 0; i < k; i++){ if(s[i] == '-') ans = (ans - quickpow(a, n-i) * quickpow(b, i) % mod + mod) % mod; else ans = (ans + quickpow(a, n-i) * quickpow(b, i) % mod + mod) % mod; } ll t = quickpow(b, k) * quickpow(a, k * (mod - 2)) % mod; if(t == 1){ ans = ans * times % mod; } else{ ans = ans * (quickpow(t, times) - 1) % mod * quickpow(t - 1, mod - 2) % mod; } cout << ans << endl; return 0; }over