1. 程式人生 > >Codeforces 964C Alternating Sum

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 k

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+9.

ExamplesInput
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;
}

.