Codeforces 963 A. Alternating Sum(快速幂,逆元)


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

猜你喜欢

转载自www.cnblogs.com/orangee/p/9094357.html