luogu P3811线性求逆元

首先扩O:T了一个点(因为上界松),83分。

#include <cstdio>
using namespace std;

int n, p;

void exgcd(int a, int p, int &b, int &x){
    if (p==0){
        b=1, x=0;
        return;
    }
    exgcd(p, a%p, b, x);
    int tmp=b;
    b=x;
    x=tmp-a/p*x;
    return;
}

int main(){
    scanf("%d%d", &n, &p);
    int x, y;
    for (int i=1; i<=n; ++i){
        exgcd(i, p, x, y);
        printf("%d\n", (x+p)%p);
    }
    return 0;
}

然后费马,事实证明果然更慢,上界很紧。

#include <cstdio>
using namespace std;

int n, p;

int expower(int a, int pow, int mod){
    int ans=1;
    while (pow){
        if (pow&1) ans=1LL*ans*a%mod;
        a=1LL*a*a%mod;
        pow>>=1;
    }
    return ans;
}

int main(){
    scanf("%d%d", &n, &p);
    for (int i=1; i<=n; ++i){
        printf("%d\n", expower(i, p-2, p));
    }
    return 0;
}

正解:首先$1^{-1} \equiv 1 \pmod p$

我们设:$p = k\cdot i + r,~r < i,~1 < i < p$

将其放在模p意义下:$k\cdot i + r \equiv 0 \pmod p$

两边同乘i-1,r-1就会得到:

$\begin{eqnarray*} k\cdot r^{-1} + i^{-1} &\equiv& 0 &\pmod p\\ i^{-1} &\equiv& -k\cdot r^{-1} &\pmod p\\ i^{-1} &\equiv& -\left\lfloor\frac{p}{i}\right\rfloor\cdot \left(p\bmod i\right)^{-1} &\pmod p\ \end{eqnarray*}$

于是核心代码就一行:

A[i] = -(p / i) * A[p % i];

我的代码:

注意:有可能是负数

#include <cstdio>
using namespace std;

const int maxn=3000000;
int n, p, a[maxn];

int main(){
    scanf("%d%d", &n, &p);
    a[1]=1;
    printf("%d\n", a[1]);
    for (int i=2; i<=n; ++i){
        a[i]=(1LL*-(p/i)*a[p%i])%p;
        a[i]=(a[i]+p)%p;
        printf("%d\n", a[i]);
    }
    return 0;
}
时间: 2024-08-29 11:34:46

luogu P3811线性求逆元的相关文章

线性求逆元

简介 逆元,简单的来说就是a?b≡1(modp),那么b就是a关于p的逆元. 正常的来说用扩展欧几里得来做.复杂度不是线性的. 但是如果所有的i≤p,有一个线性求逆元的方法. 正常的来说 方法 因为i≤p,所以考虑用i来表示p,并要求表示出来的所有数都能用p和i表示. 设p=ki+b,k=?pi?,l=pmodi 那么ki+b≡0(modp) 因为要求的是i?1,所以需要把i?1独立起来,所以我们等式两边同时乘以i?1b?1 那么式子就可以变成kb?1+i?1≡0 然后把可以求得i的逆元的数放到

线性求逆元推导

本篇介绍线性求逆元的推导过程 ·对于一个质数\(P\),我们需要求出\(1-N\)在\(mod\ P\)意义下的逆元,如何使用线性的方法求其逆元呢? ·首先,我们设\(t=P/i,k=P%i\); ·对于\(i*t+k≡0 \pmod{P}\),我们可以做出如下推导: ·等式两边同时除以\(i*k\),我们可以得到新式子\(\frac{t}{k}+\frac{1}{i}≡0 \pmod{P}\); ·从而得到:\(\frac{P}{i}*inv[P\%i]+inv[i]≡0 \pmod{P}\)

Luogu P3811 [模板]乘法逆元 题解报告

题目传送门 [题目大意] 给定$n$,求$1-n$在膜$p$意义下的乘法逆元. [思路分析] 好的原本我只会求单个数的逆元,然后被告知了这道题之后发现自己不会做(我果然还是太弱了),于是就学了一下递推求逆元. 设$p=k*i+r$,则可得$k*i+r\equiv0(mod\ p)$,然后乘上$i^{-1},r^{-1}$即可得到$k*r^{-1}+i^{-1}\equiv0(mod\ p)$ 由于$k=\lfloor \frac{p}{i}\rfloor,r=p\ mod\ i$,所以$i^{-

[uva11174]村民排队 递推+组合数+线性求逆元

n(n<=40000)个村民排成一列,每个人不能排在自己父亲的前面,有些人的父亲不一定在.问有多少种方案. 父子关系组成一个森林,加一个虚拟根rt,转化成一棵树. 假设f[i]表示以i为根的子树的排列方案数. f[i]=f[1]*f[2]*..f[k] /(sum[i]-1)!/sum[1]!*sum[2]!*..sum[k]!) 化简,对每一个i,sum[i]-1在分子出现一次,sum[i]在分母出现一次. Ans = n!/(sum1*sum2*sum3*...*sumn) 1 #inclu

求逆元的四种算法(拓欧费马小线性推欧拉)

求逆元的四种算法 拓展欧几里得算法求逆元 上一篇博客中已经讲过拓展欧几里得算法,并且讲解了求逆元的原理.这里只列出代码 在要求逆元的数与p互质时使用 代码 //扩展欧几里得定理 int ex_gcd(int a,int b,int& x,int& y) { if(b==0) { x=1; y=0; return a; } int ans = ex_gcd(b,a%b,x,y); int tmp = x; x = y; y = tmp-a/b*y; return ans; } int cal

【BZOJ3823】【East!模拟赛_Round5T1】定情信物 推公式+线性筛逆元(推公式法比出题人简)

题解1: 我们定义点为0维元素.线为1维元素.面为2维元素-- 既然一个低维超方体在对应新轴上平移得到高一维的超方体,比如二维超方体为一个面,然后沿新出现的z轴拓展,那么一个低维元素就会增加一维变成高一维的元素,比如点变成线.线变成面.面变成体-- 这样就有一个推式: 高维元素会由第一维的元素衍生.同维元素复制保留, 也就是一个超方体升维之后,高维超方体第i维元素的数量将是原超方体第i维的数量*2+(i-1)维的数量. 然后经过鬼畜的推导/撞大运的找规律,可以得到一个组合数公式, 最后加个线性筛

拓展欧几里得求逆元与阶乘逆元求法

目录 什么是逆元 如何求逆元 阶乘逆元 本文章内,若无特殊说明,数字指的是整数,除法指的是整除. 什么是逆元 我们称\(a\)是\(b\)在模\(p\)情况下的逆元,则有\(a \times b \equiv 1 ( mod\,\,p)\). 所以呢,我们其实可以将逆元看成一个数的相反数.所以在除以一个数的时候,就相当于乘上它的相反数. 如何求逆元 我们先来看看什么情况下有逆元. 当且仅当\(gcd(b,p)=1\)时,\(b\)在模\(p\)情况下有逆元. 这个结论可由裴蜀定理显然推得,下面一

(数论)简单总结求逆元的几种方法

逆元(Inverse element),如a?b≡1(modp),那么a,b互为模p意义下的逆元,则p|(a/c-b*c)(即a/c与b*c同余). 常用的求逆元方法有 1.费马小定理 若p为素数,且gcd(a,p)=1,则a^(p-1)≡1(mod p),即a*a^(p-2)≡1(mod p),故a的逆元为a^p-2. 2.拓展欧几里德算法(递推再回溯) 当gcd(A,B)|C时,可求二元一次方程Ax+By=C的整数通解. 3.逆元线性筛 递推公式:inv[i]=inv[p % i] * (p

luogu P4238 多项式求逆 (模板题、FFT)

手动博客搬家: 本文发表于20181125 13:21:46, 原地址https://blog.csdn.net/suncongbo/article/details/84485718 题目链接: https://www.luogu.org/problemnew/show/P4238 题意: 给定\(n\)次多项式\(A(x)\), 求\(n\)次多项式\(B(x)\)满足\(B(x)A(x)\equiv 1(\mod x^n)\) 题解: DFT,每个数对\(998244353\)求逆元.IDF