Codeforces 964C Alternating Sum

You are given two integers a and b. Moreover, you are given a sequence s0,s1,,sn. All values in s are integers 1 or 1. It's known that sequence is k-periodic and k divides n+1. In other words, for each kin it's satisfied that si=sik.Find out the non-negative remainder of division of ni=0sianibi by 109+9.Note that the modulo is unusual!

Input

The first line contains four integers n,a,b and k (1n109,1a,b109,1k105).

The second line contains a sequence of length k consisting of characters '+' and '-'. If the i -th character (0-indexed) is'+', then si=1, otherwise si=1.

Note that only the first kmembers 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+9.

Examples
Input
2 2 3 3
+-+
Output
7
Input
4 1 5 1
-
Output
999999228
Note

In the first example:

(ni=0sianibi)

= 22302131+2032

= 7

In the second example:

(ni=0sianibi)=14501351125211531054=781999999228(mod109+9


题意:

给你一个公式,给你一个k个字符,表示前k个的加减规则,然后就是让你求(n+1)/k 这段长度中的值,对1e9+9取余。

解题思路:

    我们可以很快的从题目中看到这是一个等比数列,求前(n+1)/k项的和,比例系数为(b/a)^k 但是我们不能忘记了这个比例系数为1的特殊情况。然后就是用快速幂加速,用扩展GCD求逆元。


#include<stdio.h>
#include<string.h>
#include<algorithm>
#define  ll long long
using namespace std;
const long long mo=1e9+9;
const int maxn=1e5+10;
ll n,a,b,k;
char ch[maxn];
ll find(ll a,ll t){
	ll res=1;
	while(t){
		if(t&1) res=res*a%mo;
		a=(a*a)%mo;
		t/=2;
	}
	return (res+mo)%mo;
}
ll ex_gcd(ll a,ll b,ll &x,ll &y){
	if(!b){
		x=1,y=0;return a;
	}
	ll te=ex_gcd(b,a%b,x,y);
	ll t=x;
	x=y;
	y=t-(a/b)*x;
	return te;
}
ll NY(ll nu){
	ll x,y;  
	ex_gcd(nu,mo,x,y);
	return (x+mo)%mo;
}
int main(){
	int i,j;
	scanf("%I64d%I64d%I64d%I64d",&n,&a,&b,&k);
	scanf("%s",ch);
	ll ans=0,m=(n+1)/k;
	for(i=0;i<k;i++){
		ll t1=find(a,n-i),t2=find(b,i);
		ll temp=t1*t2%mo;
		if(ch[i]=='+')
			ans+=temp;
		else
			ans-=temp;
		ans+=mo;
		ans%=mo;
	}
	ll q=find(NY(a),k)*find(b,k)%mo;
	if(q==1){
		ans=ans*m%mo;
	}
	else{
		long long t1=NY(q-1)%mo;
		ans=(ans*(find(q,m)-1)%mo)*t1%mo;
		ans%=mo;
	}
	ans=(ans+mo)%mo;
	printf("%I64d\n",ans);
	return 0;
}

.

猜你喜欢

转载自blog.csdn.net/bao___zi/article/details/79992264