Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 2) C.Alternating Sum(等比数列求和)

题目链接;点击打开链接

题目大意:给出一个数列s,其中的元素为s1,s2,s3......sn。元素要么是1(用‘+’表示),要么是-1(用‘-’表示)

这个数列以k个数为一个周期,且n能被k整除。

给出两个数a,b,求


题目思路:

很显然,这个求和公式中,相邻两项的比值的绝对值都是确定,都是b/a。

那么这道题首先想到的就是等比数列求和公式。

但是因为si这个系数,可能是正,可能是负,所以不能直接等比数列求和。

这时候就要用到题目中k个周期的条件,将每个周期的和看做是一项,那么相邻两项的比值就是确定的b^k/a^k。

然后就可以用等比数列求和公式了

注意:

1.除以a,要改成乘以a的逆元。  因为mod=1e9+9是质数,用费马小定理得逆元为pow(a,mod-2)

2.当比值为1时,公式中的分母1-q为0,会出错,所以要特判

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MD=1e9+9;
ll po(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%MD;
        b>>=1,a=a*a%MD;
    }
    return ans;
}
int main()
{
    ll n,a,b,k;
    cin>>n>>a>>b>>k;
    string s;
    cin>>s;
    ll cur=0;
    for(int i=0;i<k;i++)
    {
        if(s[i]=='+')cur=(cur+po(a,n-i)*po(b,i)%MD)%MD;
        else cur=(cur-po(a,n-i)*po(b,i)%MD+MD)%MD;
    }
    ll t=po(a,k*(MD-2))*po(b,k)%MD;
    if(t==1)
        cout<<cur*((n+1)/k)%MD;
    else
        cout<<cur*po(t-1,MD-2)%MD*(po(t,(n+1)/k)-1)%MD;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值