Codeforces Round #475 (Div. 2) C. Alternating Sum(等比数列+逆元)

C. Alternating Sum
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 kink≤i≤n it's satisfied that si=siksi=si−k.

Find out the non-negative remainder of division of ni=0sianibi∑i=0nsian−ibi by 109+9109+9.

Note that the modulo is unusual!

Input

The first line contains four integers n,a,bn,a,b and kk (1n109,1a,b109,1k105)(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

Output a single integer — value of given expression modulo 109+9109+9.

Examples
input
Copy
2 2 3 3
+-+
output
Copy
7
input
Copy
4 1 5 1
-
output
Copy
999999228
Note

In the first example:

(ni=0sianibi)(∑i=0nsian−ibi) = 22302131+20322230−2131+2032 = 7

In the second example:

(ni=0sianibi)=14501351125211531054=781999999228(mod109+9)(∑i=0nsian−ibi)=−1450−1351−1252−1153−1054=−781≡999999228(mod109+9).

题意: 求解(ni=0sianibi)(∑i=0nsian−ibi) ,
si



要么是-要么是+,给出1-k的si, 对于 kink≤i≤n 则有si=siksi=si−k

对于i, i+k, i + 2 *k.....可发现公比是(b/a)^k的等比数列,因为求和公式为a1(1-q^n)/(1-q),(1-q^x)/(1-q)是一样的,所以计算出

1-k的(ki=0sianibi)在乘以(1-q^x)/(1-q)即可,项数x = (n+1)/k, 取模的时候,除法要逆元,用费马小定理即可。


#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/hash_set>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
#define XINF INT_MAX
#define INF 0x3F3F3F3F
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
#define RIT reverse_iterator
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
typedef tree<PII, null_type, greater<PII>, rb_tree_tag, tree_order_statistics_node_update > rb_tree_set;
typedef tree<PII, PII, greater<PII>, rb_tree_tag, tree_order_statistics_node_update > rb_tree;
#define PQ std::priority_queue
#define HEAP __gnu_pbds::priority_queue
#define X first
#define Y second
#define lson(X) ((X)<<1)
#define rson(X) ((X)<<1|1)
#define N 110
#define M 200010
const ll  mod = 1e9 + 9;
ll q_pow(ll a, ll b)
{
	ll ans = 1;
	while(b) {
		if(b & 1)
			ans = ans * a % mod;
		a = a * a %mod;
		b >>= 1;
	}
	return ans;
}
int main()
{
	ll sum = 0, ans  = 0;
	ll a, b, k, n;
	scanf("%lld%lld%lld%lld", &n, &a, &b, &k);
	getchar();
	char ch;
	ll head = q_pow(a, n);
	ll ni_a = q_pow(a, mod-2);
	REP(i, k) {
		scanf("%c", &ch);
		if(ch == '+')
			ans = (ans + head) % mod;
		else
			ans = (ans - head + mod) % mod;
		head = head * ni_a % mod * b % mod;
	}
	ll x = (n+1) / k;
	//ll q = q_pow(q_pow(a, k), mod-2) * q_pow(b, k) % mod;
	ll q = q_pow(b*ni_a%mod, k);
    if(q == 1) {
        printf("%lld\n", ans * x % mod);
    }else {
        sum = (1 - q_pow(q, x) + mod) % mod;    //负数取模.
        sum = sum * q_pow((1-q+mod)%mod, mod-2) % mod;
        printf("%lld\n", ans * sum % mod);
    }
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值