before 

在求解除法取模问题(a / b) % m时,我们可以转化为(a % (b * m)) / b,
但是如果b很大,则会出现爆精度问题,所以我们避免使用除法直接计算。
(逆元就像是倒数一样的东西吧??)

可以使用逆元将除法转换为乘法:
  假设b存在乘法逆元,即与m互质(充要条件)。设c是b的逆元,即b * c≡1(modm),那么有a/b=(a/b)*1=(a/b)*b*c=a*c(%m)
  即,除以一个数取模等于乘以这个数的逆元取模。

注意:在模意义下的加减乘运算都是具有封闭性的,但除法确是例外,所以我们就要找一种在模意义下代替除法运算的东西.

乘法逆元定义  --  若正整数 a,b,p 满足a*b=1(% p),则a,b互为逆元,记b=inv(a)或b=a^(-1).

比如说, 在模7 意义下,3 的乘法逆元是5, 也可以说模7 意义下5的乘法逆元是3.
   问: 模13 意义下5 的逆元是什么? asnwer:8
   问: 模6 意义下2 的逆元是什么? answer: .

定理 -- (乘法逆元存在性定理)
考虑同余方程:
                  ab ≡ 1(mod p)
  若a 与p 互质, 则一定存在一个正整数解b, 满 b < p.
  若a 与p 不互质, 则一定不存在正整数解b.
  意思也就是说, 互质与乘法逆元存在互为充要条件.
证明:(ZL)

now

求解乘法逆元一般有三种方法:
  1.逆元求解一般利用扩展欧几里得。
  2.当p为质数的时候直接使用费马小定理,p非质数使用欧拉函数。
  3.当p为质数的时候,神奇的线性方法。

首先来说一下扩展欧几里得求逆元

  对于一个数a,求其在 % p 下的逆元b,就是求ab ≡ 1(mod p)

  证明:

     上式变化:

        a * x + b * y = 1;
     由欧几里得有:
        gcd( a , b )=gcd( b , a % b );
     得
        a * x + b * y = b * x2 + (a % b) * y2;
     推得:
        a % b = a - a / b * b;
     将其代入原式化简得:
        a * x + b * y = b * x2 + ( a - a / b * b ) y2;
     所以:
        a * x + b * y = b * x2 + a * y2 - a / b * b * y2
        x = y2,y = x2 - a / b * y2;
     于是可以递归求解.
     易得当 b = 0 时,x = 1 ,y = 0 , 这也就是递归的边界.

 code

int exgcd(int a,int b,int &x,int &y)
{
if(b==)
{
x=,y=;
return a;
}
int r=exgcd(b,a%b,x,y),tmp;
tmp=x,x=y,y=tmp-a/b*y;
return r;
}

然后费马小定理求解逆元

费马小定理求解逆元(up):仅仅当p为质数的时.

  各种情况的证明

  TL1. 在p是素数的情况下,对任意整数x都有x^p≡x(mod)p。
  TL2. 如果x无法被p整除,则有x^(p-1)≡1(modp)。
  TL3. 可以在p为素数的情况下求出一个数的逆元,x*x^(p-2)≡1(modp),x^(p-2)即为逆元.

  TL1.证明:
  首先强调p是素数
  那么将p次方拆开,用每个数 % p,将会得到一个 < = p 的数k ,k 的p次方的形式,由于p
  是一个质数,那么,k 如果 不是 1,它就一定与 p 互质,然后根据 费马小定理证明.
  ( x * x * x * x * x * x * x ) % 7 = ( y * y * y * y * y * y * y ) % 7
  TL2.证明:
  费马小定理正理
  TL3.证明:
  根据费马小定理 a ^ ( p - 1 ) = 1 ( % p ).

综上我们可以知道代码就是快速幂嘛

code

int fast_pow(int x,int p)
{
int now=;
while(p)
{
if(p&)
{
now=now*x;
}
x=x*x;
p>>=;
}
return now;
}

最后神奇的线性求逆元

ab = 1(mod p),求b

p%a = p-(p/a)*a;  在c++中/为整除。

(p/a)*a = p-(p%a);  换下位置

(p/a)*a = -(p%a);  在模p意义下p可以约掉,可以没有这一步

a = -(p%a)/(p/a);  再换一下位置

a-1 = -(p%a)-1*(p/a);

所以a-1可以用(p%a)-1推出,所以就可以用递推式来推出1到a的所有数的逆元。

code

int inv[];
void INV(int a,int p)
{
inv[] = ;
for (int i=; i<=a; ++i)
inv[i] = (-(p/i))*inv[p%i]%p;
}

  同时间思考下可以通过上述方法递归求解一个数的逆元

int INV(int a)
{
if (a==) return ;
return ((-(p/a)*INV(p%a))%p);
}

IMPORTANT:欧拉函数求解逆元

请参考:http://blog.csdn.net/yukizzz/article/details/51105009

欧拉函数:

令ϕ(m)表示小于等于m且与m互素的正整数的个数。 
如果x和m互质,则有xϕ(m)≡1(modm),即x×xϕ(m)−1≡1(modm),xϕ(m)−1即为x的逆元。 
在m为质数的情况下,ϕ(m)=m−1,即为费马小定理。

代码:

关键是求出欧拉函数的值。 
利用欧拉函数的积性性质

对于任意整数n,可以将它分解n=pk11∗pk22∗pk33...pkmm,其中pi为质数。

其中ϕ(n)=ϕ(p1k1)∗ϕ(pk22)...ϕ(pkmm)

最后转化为ϕ(n)=n∗∏(pi−1)/pi

对给定n进行整数分解。时间复杂度O(n√)。

int eurler_phi(int n)
{
int res = n;
for(int i = ; i * i <= n; i++){
if(n % i == ){
res = res / i * (i - );
while(n % i == ) n /= i;
}
}
if(n != ) res = res / n * (n - );
return res;
}

筛法求欧拉函数值的表,利用埃氏筛法,每次发现质因子就把他的倍数的欧拉函数乘上(p−1)∗p。 
ACdreamers博客里介绍,利用定理进行优化 
【update】这个定理是有用的,但是个人觉得他对偶数预处理的写法并没有啥用

code

int euler[maxn];
void euler_phi2()
{
for(int i = ; i < maxn; i++) euler[i] = i;
for(int i = ; i < maxn; ++i){
if(euler[i] == i){
for(int j = i; j < maxn; j += i){
euler[j] = euler[j] / i * (i - );
}
}
}
}

当n为奇数时,有ϕ(2n)=ϕ(n)

因为2n是偶数,偶数与偶数一定不互素,所以只考虑2n与小于它的奇数互素的情况,则恰好就等于n的欧拉函数值。

something about 乘法逆元的更多相关文章

  1. Bzoj2154 Crash的数字表格 乘法逆元+莫比乌斯反演(TLE)

    题意:求sigma{lcm(i,j)},1<=i<=n,1<=j<=m 不妨令n<=m 首先把lcm(i,j)转成i*j/gcd(i,j) 正解不会...总之最后化出来的 ...

  2. 51nod1256(乘法逆元)

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1256 题意:中文题诶~ 思路: M, N 互质, 求满足 K ...

  3. 【板子】gcd、exgcd、乘法逆元、快速幂、快速乘、筛素数、快速求逆元、组合数

    1.gcd int gcd(int a,int b){ return b?gcd(b,a%b):a; } 2.扩展gcd )extend great common divisor ll exgcd(l ...

  4. HDU 5651 计算回文串个数问题(有重复的全排列、乘法逆元、费马小定理)

    原题: http://acm.hdu.edu.cn/showproblem.php?pid=5651 很容易看出来的是,如果一个字符串中,多于一个字母出现奇数次,则该字符串无法形成回文串,因为不能删减 ...

  5. Codeforces 543D Road Improvement(树形DP + 乘法逆元)

    题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...

  6. HDU 1452 (约数和+乘法逆元)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1452 题目大意:求2004^X所有约数和,结果mod 29. 解题思路: ①整数唯一分解定理: 一个 ...

  7. HDU 1576 (乘法逆元)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1576 题目大意:求(A/B)mod 9973.但是给出的A是mod形式n,n=A%9973. 解题思 ...

  8. 51Nod 1256 乘法逆元 Label:exgcd

    1256 乘法逆元 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K ...

  9. hdu 2669 Romantic (乘法逆元)

    Romantic Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  10. HDU3037 Saving Beans(Lucas定理+乘法逆元)

    题目大概问小于等于m个的物品放到n个地方有几种方法. 即解这个n元一次方程的非负整数解的个数$x_1+x_2+x_3+\dots+x_n=y$,其中0<=y<=m. 这个方程的非负整数解个 ...

随机推荐

  1. 回文树/回文自动机(PAM)学习笔记

    回文树(也就是回文自动机)实际上是奇偶两棵树,每一个节点代表一个本质不同的回文子串(一棵树上的串长度全部是奇数,另一棵全部是偶数),原串中每一个本质不同的回文子串都在树上出现一次且仅一次. 一个节点的 ...

  2. Golang ---json解析

    golang官方为我们提供了标准的json解析库–encoding/json,大部分情况下,使用它已经够用了.不过这个解析包有个很大的问题–性能.它不够快,如果我们开发高性能.高并发的网络服务就无法满 ...

  3. left join 左边有数据,右边无数据

     参考了链接: https://blog.csdn.net/chenjianandiyi/article/details/52402011   主要是and和where的区别:   原Sql: Con ...

  4. C# vb .net实现锐化效果滤镜

    在.net中,如何简单快捷地实现Photoshop滤镜组中的锐化效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...

  5. Oracle PLSQL数据导出csv的案例

    之前项目运维人员碰到一个问题,需要写一个存储过程,把数据导出为csv文件,查了一些资料,帮他写成了一个PLSQL,今天拿出来分享一下,不足之处,欢迎指教. 数据背景:  用到两张表,一张存放单位组织名 ...

  6. Maven打包时集成依赖项或复制依赖项到指定目录

    1.集成依赖项,最后生成的jar文件包含所有依赖: <build> <plugins> <plugin> <artifactId>maven-assem ...

  7. vue-quill-edito 字体倾斜加粗无效

    长话短说,出现这种情况的原因80%-90%的概率在你项目里面有一个全局的 一般在reset.css重置文件中 font-weight:normal; font-style:normal; font-s ...

  8. watch from Middle English wacche

    watch As a noun, from Middle English wacche, Etymology As a noun, from Middle English wacche,See bel ...

  9. ETL 的一些概念

    1. What is a logical data mapping and what does it mean to the ETL team? 什么是逻辑数据映射?它对ETL项目组的作用是什么? 答 ...

  10. influxDB应用及TICK stack

    InfluxData平台用于处理度量和事件的时间序列平台,常被称为TICK stack,包含4个组件:Telegraf,influxDB,Chronograf和Kapacitor,分别负责时间序列数据 ...