当前位置: 代码迷 >> 综合 >> Codeforces Round #475 (Div. 2) C. Alternating Sum(等比数列+逆元)
  详细解决方案

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

热度:94   发布时间:2023-11-24 22:31:04.0

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=si?ksi=si?k.

Find out the non-negative remainder of division of ni=0sian?ibi∑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=0sian?ibi)(∑i=0nsian?ibi) = 2230?2131+20322230?2131+2032 = 7

In the second example:

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

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



要么是-要么是+,给出1-k的si, 对于 kink≤i≤n 则有si=si?ksi=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=0sian?ibi)在乘以(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;elseans = (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;
}



  相关解决方案