线性推逆元法

给你一个p,要你求出1~p-1所有数在模p下的逆元。

一个一个用扩展欧几里得求?如果p特别大,不就超时了?我们想要在线性的时间复杂度内求出逆元。

这种方法只能在p为质数的情况下使用。

首先有$1^{-1}\equiv 1(mod\ p)$

设$p=iq+r(0<r<p)$,在模p意义下得$iq+r\equiv 0(mod\ p)$。

两边同时乘$i^{-1}$和$r^{-1}$得:$$qr^{-1}+i^{-1}\equiv 0(mod\ p)$$

$$i^{-1}\equiv -qr^{-1}(mod\ p)$$

$$i^{-1}\equiv -\lfloor \frac{p}{i}\rfloor (p\ mod\ i)^{-1}(mod\ p)$$

$$i^{-1}\equiv (p-\lfloor \frac{p}{i}\rfloor)(p\ mod\ i)^{-1}(mod\ p)$$

所以我们只要线性推一下即可。时间复杂度$\theta(n)$

所以代码如下:

inv[1]=1;
for(int i=2;i<p;++i)
inv[i]=(p-p/i)*inv[p%i]%p;
时间: 2024-11-10 15:30:11

线性推逆元法的相关文章

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

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

线性求逆元

简介 逆元,简单的来说就是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的逆元的数放到

线性差值法结构类(面向对象的方式)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication7 { public enum PointState { Inner = 0,//定义域的点 Mid = 1,//未超出定义域的点 LeftOuter = 2,//超出左侧 RightOuter = 3//超出右

线性求逆元推导

本篇介绍线性求逆元的推导过程 ·对于一个质数\(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}\)

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

求逆元的四种算法 拓展欧几里得算法求逆元 上一篇博客中已经讲过拓展欧几里得算法,并且讲解了求逆元的原理.这里只列出代码 在要求逆元的数与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

[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

53.Maximum Subarray(法1线性扫面法2分治法)

Find the contiguous subarray within an array (containing at least onenumber) which has the largest sum. For example, given the array [?2,1,?3,4,?1,2,1,?5,4], the contiguous subarray [4,?1,2,1] has thelargest sum = 6. click to showmore practice. HideT

ACM学习历程—SNNUOJ 1110 A Simple Problem(递推 &amp;&amp; 逆元 &amp;&amp; 组合数学 &amp;&amp; 快速幂)(2015陕西省大学生程序设计竞赛K题)

Description Assuming a finite – radius “ball” which is on an N dimension is cut with a “knife” of N-1 dimension. How many pieces will the “ball” be cut into most?However, it’s impossible to understand the following statement without any explanation.L

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",