牛牛的函数 解题报告

给定,那么可以根据等比数列求和得到:
那么如果求 ,我们可以将等比数列求和之后的f(x)拆开计算,即求:
其中 即求关于 M 的逆元。
所以就转化为求两个个快速幂,然后在求一个逆元即可。但是有一个trick,就是M的范围是long long 的,所以在求快速幂的过程要加上一个快速乘法,因为两个long long相乘超过long long的值了。
时间复杂度:O((logn)^2)
空间复杂度:O(1)
代码如下:

typedef long long LL;
const LL MOD = 10000000033;
LL Multi(LL a, LL b){
    LL ans = 0;
    while(b){
        if(b & 1) ans = (ans + a) % MOD;
        b>>=1;
        a = (a + a) % MOD;
    }
    return ans;
}
LL Pow(LL a, LL b){
    LL ans = 1;
    while(b){
        if(b & 1) ans = Multi(ans, a);
        b>>=1;
        a = Multi(a, a);
    }
    return ans;
}
void Exgcd(LL a, LL b, LL &x, LL &y){
    if(b == 0){
        x = 1;
        y = 0;
        return;
    }
    LL x1, y1;
    Exgcd(b, a%b, x1, y1);
    x = y1;
    y = x1 - (a/b)*y1;
}
class Solution {
public:
    /**
     * 
     * @param a int整型 
     * @param b int整型 
     * @param n int整型 
     * @return long长整型
     */
    long long solve(int a, int b, int n) {
        // write code here
        if(n == 0) return 0;
        if(n == 1) return b-a+1;
        LL ans = Pow(n, a);
        LL x, y;
        Exgcd(n-1, MOD, x, y);
        x = (x%MOD+MOD)%MOD;
        ans = Multi(ans, x);
        ans = Multi(ans, (Pow(n, b-a+1)-1));
        ans = (ans%MOD+MOD)%MOD;
        return ans;
    }
};
全部评论

相关推荐

求求给个offer我...:有这60不如v我50
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务