题目链接:点击打开链接
题目大意:给一个序列只含'-'和 '+',长度为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