快速幂+等比数列前n项求和并取模+求逆元

题目链接:https://acm.zzuli.edu.cn/zzuliacm/problem.php?cid=1242&pid=4

解法:题中给是求一个等比数列的前n项和取模(1e9+7),已知等比数列前n项求和公式为\(s=\frac{a_1(q^n-1)}{q-1}\),现在求前n+1项即可,q==1的时候特判断。但是比较麻烦的是需要取模,也就是我们要求的结果实际是\(s=\frac{q^{n+1}-1}{q-1}\ mod\ (1e9 + 7)\),注意我们求\(q^{n+1} - 1\)时是使用的快速幂算法,已经取过模了,如果与\(q-1\)相除再求模结果会错,所以我们要把\(\frac{x}{y}\ mod\ p\)的形式改为等价的\(x*z\ mod\ p\)的形式。

替换的方法:(参考于http://blog.csdn.net/mengxiang000000/article/details/53468865)

逆元的定义:若有\(A*x\equiv 1(mod\ y)\)其中A是最小满足这个式子的数,则A就是x对y的逆元。
如果有:
\(s = \frac{x}{y} \ mod\ p\),那么我们就可已寻找y对p的逆元,使得出发变成乘法;若此时设定z为y的逆元,则有\(s\equiv \frac{x}{y} * (y*z) \ mod\ p\),即\(s\equiv x*y\ mod\ p\)

参考代码:

注意是参考代码,不一定可以AC,应该会有一些细节有问题

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

typedef long long LL;

const LL MOD = 1000000007;

LL mod_pow(LL x, LL n){
    LL res = 1;
    while (n > 0){
        if (n & 1) res = res * x % MOD;
        x = x * x % MOD;
        n >>= 1;
    }
    return res;
}

LL exgcd(LL m, LL n, LL &x, LL &y){
    LL x1, y1, x0, y0;
    x0 = 1; y0 = 0;
    x1 = 0; y1 = 1;
    LL r = (m % n + n) % n;
    LL q = (m - r) / n;
    x = 0; y = 1;
    while(r){
        x = x0 - q * x1; y = y0 - q * y1; x0 = x1 ;y0 = y1;
        x1 = x; y1 = y;
        m = n; n = r; r = m % n;
        q = (m - r) / n;
    }
    return n;
}

LL cal(LL a, LL m){
    LL x, y;
    LL gcd = exgcd(a, m, x, y);
    m = m < 0 ? -m : m;
    x = (x % m + m) % m;
    return x;
}

int main(){
    LL cs = 0;
    LL k, n;
    while (~scanf("%lld%lld", &k, &n)){
        if (k == 1){
            printf("Case %lld: %lld\n", ++cs, (n + 1) % MOD);
        }
        else{
            //求逆元
            LL z = cal(k - 1, MOD);
            //注意这里求x的方式,没有直接用q^(n+1)-1
            LL x = mod_pow(k, n + 1);
            if (x == 0){
                x = MOD - 1;
            }
            else{
                x = x - 1;
            }
            LL res = x * z % MOD;
            printf("Case %lld: %lld\n", ++cs, res);
        }
    }
    return 0;
}
发布了10 篇原创文章 · 获赞 3 · 访问量 869

猜你喜欢

转载自blog.csdn.net/ErrorNam/article/details/82976369
今日推荐