You are given two integers aa and bb. Moreover, you are given a sequence s0,s1,…,sns0,s1,…,sn. All values in ss are integers 11 or −1−1. It's known that sequence is kk-periodic and kk divides n+1n+1. In other words, for each k≤i≤nk≤i≤n it's satisfied that si=si−ksi=si−k.
Find out the non-negative remainder of division of n∑i=0sian−ibi∑i=0nsian−ibi by 109+9109+9.
Note that the modulo is unusual!
The first line contains four integers n,a,bn,a,b and kk (1≤n≤109,1≤a,b≤109,1≤k≤105)(1≤n≤109,1≤a,b≤109,1≤k≤105).
The second line contains a sequence of length kk consisting of characters '+' and '-'.
If the ii-th character (0-indexed) is '+', then si=1si=1, otherwise si=−1si=−1.
Note that only the first kk members of the sequence are given, the rest can be obtained using the periodicity property.
Output a single integer — value of given expression modulo 109+9109+9.
2 2 3 3 +-+
7
4 1 5 1 -
999999228
In the first example:
(n∑i=0sian−ibi)(∑i=0nsian−ibi) = 2230−2131+20322230−2131+2032 = 7
In the second example:
(n∑i=0sian−ibi)=−1450−1351−1252−1153−1054=−781≡999999228(mod109+9)(∑i=0nsian−ibi)=−1450−1351−1252−1153−1054=−781≡999999228(mod109+9).
这道题就是等比求和,以第一个循环节为基准,比值为(b^k)/(a^k);求和次数为(n+1)/k;剩余个数为(n+1)%k;
要注意的是,如果a^k==b^k;就要进行特判,不然运用求和公式的话,会出现分母为0的情况。
用等比公式求和之后,再把剩余个数加上就好。
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<cstdio>
#define ll long long
using namespace std;
ll mod = 1e9 + 9;
ll qm(ll a, ll b)//快速幂
{
ll ans = 1;
while (b>0)
{
if (b & 1)ans = ans*a%mod;
b >>= 1; a = a*a%mod;
}
return (ans%mod + mod) % mod;
}
char c[1000005];
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
ll n, a, b, k;
cin >> n >> a >> b >> k;
cin >> c;
ll ans = 0;
if (n + 1 <= k)//n+1<=k,直接求和
{
for (ll i = 0; i <= n; i++)
{
if (c[i] == '-')
{
ans = ans - qm(a, n - i)*qm(b, i); ans = (ans%mod + mod) % mod;
}
else
{
ans = ans + qm(a, n - i)*qm(b, i); ans = (ans%mod + mod) % mod;
}
}
ans = (ans%mod + mod) % mod;
cout << ans << endl;
}
else
{
ll t = (n + 1) / k; ll g = (n + 1) % k; ll x = 0;//t为等比求和次数,g为剩余次数 x为等比数列第一项
if (g == 0)
{
for (ll i = 0; i < k; i++)
{
if (c[i] == '-')
{
x = x - qm(a, n - i)*qm(b, i); x = (x%mod + mod) % mod;
}
else
{
x = x + qm(a, n - i)*qm(b, i); x = (x%mod + mod) % mod;
}
}
if (qm(a,k)== qm(b,k)) {//特判 避免分母为0
ans = t*x; ans = (ans%mod + mod) % mod; cout << ans << endl; return 0;
}
ll jj = qm(a, t*k) - qm(b, t*k); jj = x*jj%mod; jj = jj* qm(a, k) % mod;; jj = jj%mod;
ll nn = (qm(a, k) - qm(b, k)); nn = nn%mod; nn = nn *qm(a, t*k); nn = nn%mod; nn = qm(nn, mod - 2);
ans = jj*nn; ans = (ans%mod + mod) % mod;
cout << ans << endl;
}
else
{
for (ll i = 0; i < k; i++)
{
if (c[i] == '-')
{
x = x - qm(a, n - i)*qm(b, i); x = (x%mod + mod) % mod;
}
else
{
x = x + qm(a, n - i)*qm(b, i); x = (x%mod + mod) % mod;
}
}
if (qm(a, k) == qm(b, k)) {
ans = t*x; ans = (ans%mod + mod) % mod;
for (ll hh = 0; hh < g; hh++)
{
if (c[hh] == '-')
{
ans = ans - qm(a, n - (t*k + hh))*qm(b, (t*k + hh)); ans = (ans%mod + mod) % mod;
}
else
{
ans = ans + qm(a, n - (t*k + hh))*qm(b, (t*k + hh)); ans = (ans%mod + mod) % mod;
}
}
ans = (ans%mod + mod) % mod;
cout << ans << endl; return 0;
}
ll jj = qm(a, t*k) - qm(b, t*k); jj = x*jj%mod; jj = jj* qm(a, k) % mod;; jj = jj%mod;
ll nn = (qm(a, k) - qm(b, k)); nn = nn%mod; nn = nn *qm(a, t*k); nn = nn%mod; nn = qm(nn, mod - 2);
ans = jj*nn; ans = (ans%mod + mod) % mod;
for (ll hh = 0; hh < g; hh++)
{
if (c[hh] == '-')
{
ans = ans - qm(a, n - (t*k + hh))*qm(b, (t*k + hh)); ans = (ans%mod + mod) % mod;
}
else
{
ans = ans + qm(a, n - (t*k + hh))*qm(b, (t*k + hh)); ans = (ans%mod + mod) % mod;
}
}
ans = (ans%mod + mod) % mod;
cout << ans << endl;
}
}
}