Codeforces 963 A. Alternating Sum
题目大意:给出一组长度为n+1且元素为1或者-1的数组S(0~n),数组每k个元素为一周期,保证n+1可以被k整除。给a和b,求对1e9+9取模的结果
思路:容易想到,每个周期的∑组成的数列成等比,公比q=(b/a)^k,因此可以用等比数列公式求和。为了保证时间复杂度,需要用到快速幂运算;为了防止中间过程值溢出,需要多处取模,其中用费马小定理求逆元;
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e9+9;
ll qpow(ll x,ll n,ll m)
{
ll res=1;
while (n>0)
{
if (n&1)
res=res*x%m;
n>>=1;
x=x*x%m;
}
return res;
}
ll inv(ll x,ll m)
{
return qpow(x,m-2,m);
}
int main()
{
int n,a,b,k,i;
cin>>n>>a>>b>>k;
cin.get();
ll ft=0,q,ans;
for (i=0;i<k;++i)
{
char c;
scanf("%c",&c);
if (c=='+')
{
ft=(ft+qpow(a,n-i,mod)*qpow(b,i,mod)%mod+mod)%mod;
}
else
{
ft=(ft-qpow(a,n-i,mod)*qpow(b,i,mod)%mod+mod)%mod;
}
}
q=qpow(b,k,mod)*inv(qpow(a,k,mod),mod)%mod;
if (q==1)
{
ans=ft*(n+1)/k%mod;
}
else
{
ans=ft*(qpow(q,(n+1)/k,mod)-1)%mod*inv(q-1,mod)%mod;
}
cout<<ans;
return 0;
}