• Codeforces 963E Alternating Sum 等比数列+逆元


    题目大意:

    看一下样例就明白了

    基本思路:

    题目中明确提到k为一个周期,稍作思考,把k项看作一项,然后发现这是个等比数列,q=(b/a)^k,

    然后重点就是怎样处理等比数列求和表达式中的除法,这个时候就要用到逆元,因为1e9+9是素数,

    所以直接用费马小定理求逆元就好了,说到这个,可以学一下卢卡斯定理,这个比较有用处,然后需要注意

    两点:

    1)快速幂a的每次乘方里面都要%mod,这个到底是为什么我也不知道,难道不是只在外面取模一次就好了吗

    2)最后判断条件是t2是否等于0,而不是a是否等于b,难道不是等价的吗?为什么会这样?

    代码如下:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<vector>
    
    using namespace std;
    
    typedef long long ll;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int inf = 0x3f3f3f3f;
    const int maxn = 100000+10;
    const ll mod = 1e9+9;
    
    char s[maxn];
    ll qpow(int a,int b){
        ll res=1;
        while(b){
            if(b&1) res=(res*a)%mod;
            a=(a%mod*a%mod)%mod;
            b>>=1;
        }
        return res%mod;
    }
    int main(){
        int n,a,b,k;
        scanf("%d%d%d%d",&n,&a,&b,&k);
        scanf("%s", s);
        int len = strlen(s);
        LL ans = 0;
        LL tmp, cir = 0;
        for(int i = 0; i < len; i++){
            tmp = qpow(a,n-i) * qpow(b,i) % mod;
            if(s[i] == '+') {
                cir += tmp;
                cir %= mod;
            }
            else {
                cir -= tmp;
                if(cir < 0) cir += mod;
                cir %= mod;
            }
        }
        int time = (n+1) / len;
        int lf = n+1 - len*time;
        int be = len*time;
        for(int i = 0; be <= n; i++, be++){
            tmp = qpow(a,n-be) * qpow(b,be) % mod;
            if(s[i] == '+') {
                ans += tmp;
                ans %= mod;
            }
            else {
                ans -= tmp;
                if(ans < 0) ans += mod;
                ans %= mod;
            }
        }
        ll t1=(qpow(a,len*time)-qpow(b,len*time))%mod;
        if(t1<0) t1+=mod;
        ll t2=(qpow(a,k*time)-(qpow(a,k*(time-1))*qpow(b,k)%mod))%mod;
        if(t2<0) t2+=mod;
        ll t3=t1*qpow(t2,mod-2)%mod;
        if(t2==0){
            printf("%I64d
    ",(ans+cir*time%mod)%mod);
        }else{
            printf("%I64d
    ",(ans+cir*t3%mod)%mod);
        }
        return 0;
    }
    

      

  • 相关阅读:
    2019.9.25 初级数据结构——树状数组
    2019.9.29 陪审团
    2019.9.27 硬币
    0070-星星阵
    0069-简单的回文数问题
    0068-简单的求和问题
    0067-水仙花数
    0066-若干个数求和问题
    0065-数方块
    0064-简单的平方和
  • 原文地址:https://www.cnblogs.com/imzscilovecode/p/8880022.html
Copyright © 2020-2023  润新知