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 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 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
.
Examples
Input
Copy
2 2 3 3
+-+
Output
Copy
7
Input
Copy
4 1 5 1
Output
Copy
999999228
Note
In the first example:
(n∑i=0sian−ibi)
= 2230−2131+2032
= 7
In the second example:
(n∑i=0sian−ibi)=−1450−1351−1252−1153−1054=−781≡999999228(mod109+9)
解析:由于用到取模,还要做除法运算,所以要用到逆元,我们先把连续的k个值求出来,然后求出公比p,即(b/a)^k,如果p==1那么输出x*sum,p不等于1就还要求下1-p的逆元,然后按等比数列求和公式得出结果
不清楚如何求逆元可以点下这里
一般膜都是素数,所以直接用a^(mod-2)次方求就好了
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pb push_back
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rep1(i,b,a) for(int i=b;i>=a;i--)
#define mod 1000000009
#define INF 1000000
using namespace std;
const int N=1e5+100;
int arr[N];
ll fi(ll A,ll n)
{
ll ans=1;
while(n)
{
if(n&1)
ans=(ans*A)%mod;
A=(A*A)%mod;
n>>=1;
}
return ans;
}
int main()
{
ll n,k,a,b,p,ans,sum=0,t,x;
string s;
cin>>n>>a>>b>>k>>s;
for(int i=0;i<k;i++)
{
t=fi(a,n-i)*fi(b,i)%mod;
if(s[i]=='+')
sum=(sum+t)%mod;
else
sum=(sum-t+mod)%mod;
}
x=(n+1)/k;
t=(b%mod)*fi(a,mod-2)%mod;
p=fi(t,k)%mod;
if(p==1)
{
cout<<sum*x%mod<<endl;
return 0;
}
ans=fi(p,x)%mod;
ans=(1-ans+mod)%mod;
ans=ans*fi((1-p+mod)%mod,mod-2)%mod;
cout<<(ans*sum%mod+mod)%mod<<endl;
return 0;
}