费马小定理,拓展欧几里得求逆元。zzuli 2180

本文介绍了模意义下的逆元概念及求解方法,包括费马小定理的应用和拓展欧几里得算法,并通过一道例题展示了如何在实际问题中应用这些理论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

逆元:在mod m的运算下,像满足

ax%m=1
这样的求解出的x,我们称作a的逆元即
a1

首先简介费马小定理 传送门
对于p是素数时,任意正整数都有
(xp)%p=x

然后可以推出
(xp1)%p=1

最后可以变形得到

x1%p=xp2

所以我们对于一个数求x^(p-2)就是他的逆元.

拓展欧几里得的做法,也很显然,就是求解ax + km = 1中的x就是a的逆元。

例题zzuli 2180 传送门

这个题就是求一个等比数列的前n项和,直接套用公式,不过在公式最后一部分处罚的时候要求一下逆元
代码如下

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<queue>

using namespace std;
typedef long long ll;
const ll mod = (ll)1e9+7;
ll Quick_pow(ll x,ll n){
    ll res = 1;
    while(n){
        if(n&1) res = res%mod*x%mod;
        x = x%mod*x%mod;
        n = n >> 1;
    }
    return res;
}
ll extgcd(ll a,ll b,ll &x,ll &y){
    ll res = 0;
    if(b != 0) {
        res = extgcd(b,a%b,y,x);
        y -= (a/b)*x;
    }else{
        x = 1;y = 0;
    }
    return res;
}
ll mod_inverse(ll a,ll m){
    ll x,y;
    extgcd(a, m, x, y);
    return (m + x%m)%m;//这里是为了保证x是最小的正整数
}
int main(void){
    ll k,n,Case = 0;
    while(scanf("%lld %lld",&k,&n) != EOF){
        printf("Case %lld: ",++Case);
        if(k == 1)  printf("%lld\n",n+1);
        else{
            ll p = Quick_pow(k,n+1) - 1;
            ll q = k - 1;
   //         ll x,y;
       //     ll b = Quick_pow(q,mod-2);
            ll add = mod_inverse(q,mod);
            printf("%lld\n",(p%mod)*add%mod);
        }
    }

    return 0;
}
/**************************************************************
    Problem: 2180
    User: zhao5502169
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1368 kb
****************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值