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 k≤i≤n it's satisfied that si=si−k.Find out the non-negative remainder of division of n∑i=0sian−ibi by 109+9.Note that the modulo is unusual!
Input
The first line contains four integers n,a,b and k (1≤n≤109,1≤a,b≤109,1≤k≤105).
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 a single integer — value of given expression modulo 109+9.
2 2 3 3 +-+
7
4 1 5 1 -
999999228
In the first example:
(n∑i=0sian−ibi)
= 7
In the second example:
(n∑i=0sian−ibi)=−1450−1351−1252−1153−1054=−781≡999999228(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;
}
.