1. 程式人生 > >三種求乘法逆元方法詳解

三種求乘法逆元方法詳解

題目背景

這是一道模板題

題目描述

給定n,p求1~n中所有整數在模p意義下的乘法逆元。

輸入輸出格式

輸入格式:

一行n,p

輸出格式:

n行,第i行表示i在模p意義下的逆元。

輸入輸出樣例

輸入樣例#1:
10 13
輸出樣例#1:
1
7
9
10
8
11
2
5
3
4

說明

1n3×106​​,n<p<20000528

輸入保證 p 為質數。

我們有三種辦法求逆元 

由尤拉定理可知 

當gcd(a,n)==1 時 我們有 Aφ(n-1)≡ 1(mod n) ;

所以 我們有 A*Aφ(n-2) ≡ 1(mod n) 

所以Aφ(n-2) 就是A關於mod n的逆元 

 1 /*
 2     p為素數時 可用費馬小定理 
 3     longlong*longlong 要慢一點 66分 
 4 */
 5 #include <cctype>
 6 #include <cstdio>
 7 
 8 typedef long long LL;
 9 
10 int n,p;
11 
12 inline LL quick_pow(LL a,int k) {
13     LL ret=1;
14     while(k) {
15         if(k&1) ret=(ret*a)%p;
16         k>>=1
; 17 a=(a*a)%p; 18 } 19 return ret; 20 } 21 22 int hh() { 23 scanf("%d%d",&n,&p); 24 printf("1\n"); 25 for(int i=2;i<=n;++i) { 26 LL t=quick_pow(i,p-2); 27 printf("%d\n",(t+p)%p); 28 } 29 return 0; 30 } 31 32 int sb=hh(); 33 int main(int argc,char
**argv) {;}
費馬小定理

還有我們可以用exgcd來求逆元 

我們知道 若ax≡1(mod p)  這我們可以寫成 ax=py+1;

移項則有 ax-by=1  這明顯就是擴充套件歐幾里得

當 ax+by=gcd(a,b)  gcd(a,b) == gcd(b,a%b) 

我們得到 bx1+(a-a/b)y1=gcd(b,a%b);

則 ax+by=bx1+(a-(a/b)*b)y1 //這裡 / 代表整除

   ax+by=bx1+ay1-b*(a/b)y1 

   ax+by=ay1+b(x1-(a/b)*y1) 

我們得到 x=y1

     y=x1-(a/b)*y1;

x 即為我們所求的逆元 

由於 x 可能為負數 要(x+p)%p 

 1 /*
 2     EXgcd 求逆元
 3     比費馬小定理要快一點 83分  
 4 */
 5 #include <cstdio>
 6 #include <cctype>
 7 
 8 int n,p;
 9 
10 inline int exgcd(int a,int b,int&x,int&y) {
11     if(!b) {
12         x=1;y=0;
13         return a;
14     }
15     int p=exgcd(b,a%b,x,y);
16     int t=x;
17     x=y;
18     y=t-(a/b)*y;
19     return p;
20 } 
21 
22 int hh() {
23     scanf("%d%d",&n,&p);
24     printf("1\n");
25     int x,y; 
26     for(int i=2;i<=n;++i) {
27         exgcd(i,p,x,y);
28         printf("%d\n",(x+p)%p);
29     }
30     return 0;
31 }
32 
33 int sb=hh();
34 int main(int argc,char**argv) {;}
EXgcd

但是對於 這個題來講 複雜度還是不夠 

我們還有線性求逆元的方法 

來看帶餘除法 式子 p=k*i+r 

我們可以寫成 k*i+r≡0(mod p) 

式子兩邊同乘 i-1*r-1 (i-1,r-1皆為模p意義下的逆元) 

所以我們有 k*r-1+i-1≡0(mod p) 

i-1≡-k*r-1(mod p)

i-1≡-(p/i)*(p%i)-1(mod p)

這樣我們就線性求得了逆元

 1 #include <cctype>
 2 #include <cstdio>
 3 
 4 typedef long long LL;
 5 const int MAXN=3000010;
 6 
 7 int n,p;
 8 
 9 LL inv[MAXN];
10 
11 int hh() {
12     scanf("%d%d",&n,&p);
13     printf("1\n");
14     inv[1]=1;
15     for(int i=2;i<=n;++i) {
16         inv[i]=(LL)(p-p/i)*inv[p%i]%p;
17         printf("%d\n",inv[i]);
18     }
19     return 0;
20 } 
21 
22 int sb=hh();
23 int main(int argc,char**argv) {;}
線性求逆元

相關推薦

乘法方法

題目背景 這是一道模板題 題目描述 給定n,p求1~n中所有整數在模p意義下的乘法逆元。 輸入輸出格式 輸入格式: 一行n,p 輸出格式: n行,第i行表示i在模p意義下的逆元。 輸入輸出樣

hdu1576(擴展gcd乘法)

mis pla IT cep bsp time 兩個 AI total A/B Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissi

乘法

using while pan printf ++ pre () namespace col #include<bits/stdc++.h> using namespace std; typedef long long ll; void exgcd(ll

擴充套件歐幾里得演算法(乘法

eg:求5關於模14的乘法逆元 15 = 5*2+1 5 = 4*1+1 說明5與14互素,存在5關於14的乘法逆元 1 = 5-4 = 5-(14-5*2)= 5*3-14 因此5關於模14的乘法逆元為3  a存在模b的乘法逆元的充要條件是gcd(a,b)= 1 互質

擴充套件的歐幾里德演算法乘法

計算乘法逆元,比如3mod8的乘法逆元為3 是如何用歐幾里得演算法計算的呢??? 數對 x,y ,使得 gcd(a,b)=ax+by。 c++語言實現: #include <iostream&

擴充套件歐幾里德演算法乘法(C語言版)

#include <stdio.h>   int ExtendedEuclid( int f,int d ,int *result);   int main()   {   int x,y,z;   z = 0;   printf("輸入

擴充套件歐幾里得乘法

對於正整數a和m如果滿足公式,那麼x的最小正整數解稱為a模m的逆元。 可以證明等價於 gcd(a,m)=1即a*x+m*y=1,因此如果gcd(a,m)!=1就一定是無解的。 現在就可以用擴充套件歐幾里得求x的通解了即x=x0+(m/1)t,x0%m為最小正整數解。 如果m

歐幾里得演算法(最大公因子)及擴充套件歐幾里得(乘法

一、歐幾里得演算法歐幾里得演算法又稱輾轉相除法,是指用於計算兩個正整數a,b的最大公約數。gcd(a,b)=gcd(b,a mod b)。演算法描述:1. 輸入:兩個非負整數a,b,且a≥b。2. 輸出

hadoop的執行模式區別及配置

       基於hadoop進行開發時,有時候,會被hadoop的三種執行模式搞混,也會被hadoop叢集有哪些配置弄得暈頭轉向,因為看不同的文件有不同的配置方法。所以要先弄明白hadoop的執行模

iOS 側滑選單效果對比

- (void)mainTabBar {  AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication]

create table ,create as 與create like建表方式的使用

     Hive的hql是基於sql而來,而sql中關於表的建立有幾種方式。同樣,hive也支援這些表的建立方式。      官網文件關於建表的地址:hive常見建表方式官網文件 1.自主創業方式create table&nb

Java基礎入門 - 註釋及文件註釋

類似C/C++,Java也支援單行和多行註釋 註釋中的字元在編譯時會被忽略 註釋通常為類、變數和方法的主要描述 單行註釋 // 註釋內容 多行註釋 /* 註釋內容 */ /*  * 註釋內容  */ 文件註釋 /**  * 註釋內容  */

Lua表與方法(轉)

Lua中提供的元表是用於幫助Lua資料變數完成某些非預定義功能的個性化行為,如兩個table的相加。假設a和b都是table,通過元表可以定義如何計算表示式a+b。當Lua試圖將兩個table相加時,它會先檢查兩者之一是否有元表,然後檢查該元表中是否存在_

大資料(二十三)Hive【Hive啟動方式 、 HIVE Server2 、 jdbc連結HIVE】

一:Hive的三種啟動方式 1, hive  命令列模式         進入hive安裝目錄,輸入bin/hive的執行程式,或者輸入 hive –service cli         用於linux平臺命令列查詢,查詢語句基本跟mysql查詢語句類似  2, hive

常見的http content-type

介紹         http協議是建立在tcp/ip協議之上的應用層協議,主要包括三個部分,狀態行,頭部資訊,訊息主體。對應一個http請求就是:請求行,請求頭,請求體。         協議規定post提交的資料,必須包含在訊息主體中entity-body中,但是協議

JSP頁面跳轉方法

  1. RequestDispatcher.forward() 是在伺服器端起作用,當使用forward()時,Servlet engine傳遞HTTP請求從當前的Servlet or JSP到另外一個Servlet,JSP 或普通HTML檔案,也即你的form提交至a.

乘法總結 3基本方法

逆元 逆元(inverse element)是在取模意義下,不能直接除以一個數,而要乘以它的逆元;a*b ≡ \equiv

乘法的幾計算方法

乘法逆元是數論中重要的內容,也是 ACM 中常用到的數論演算法之一。所以,如何高效的求出乘法逆元是一個值得研究的問題。 這裡我們只討論當模數為素數的情況,因為如果模數不為素數,則不一定每個數都有逆

各種方法總結[轉]

str com 情況 sans esp 找到 解法 () clu 各種求逆元方法總結[轉] 在MOD的情況下, (a*b/c ) %MOD 不能直接 / c 來求,需要找到一個數 inv 使得 inv * c % MOD = 1 。 這樣 (a*b / c) % M

HDU 1576 -- A/B (總結乘法的幾求法)

推廣 ont show 乘法逆元 ostream space 同余 乘法 個數 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others)