P3811 【模板】乘法逆元

回首望月一波之前\(logN\)求逆元的扩展欧几里得算法

(求解\(a * x \equiv 1(Mod\ p)\) \(\Leftrightarrow\) 求解 \(a * x + p * y = 1\)

LL exgcd(LL a,LL b,LL &x,LL &y){//注意引用
	if(!b){x = 1,y = 0;return a;}
	int d = exgcd(b,a % b,x,y);
	LL temp = x;x = y;y = temp - y * (a / b);
	return d;
	}
    
int main(){
	a = RD();p = RD();
    LL d = exgcd(a,p,x,y);
    printf("%d\n",x);
    return 0;
	}

P3811 【模板】乘法逆元

题目背景

这是一道模板题

题目描述

给定n,p求1~n中所有整数在模p意义下的乘法逆元。

输入输出格式

输入格式:

一行n,p

输出格式:

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


这次要求求出一串数的逆元之前的算法是\(nlogN\)的复杂度

但很显然承受不了,引入\(O(N)\)求一串逆元的方法(模数\(P\)为质数)

\[inv[1] = 1 \]

\[inv[{i}] = ({P - P / i}) * inv[P\; \%\;i]\;\% P \]

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
typedef long long LL;
using namespace std;
int RD(){
    int out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const int maxn = 10000019;
int a,p;
LL x,y;
LL exgcd(LL a,LL b,LL &x,LL &y){
	if(!b){x = 1,y = 0;return a;}
	int d = exgcd(b,a % b,x,y);
	LL temp = x;x = y;y = temp - y * (a / b);
	return d;
	}//放个扩欧一起好了(才不是什么第一次扩欧TLE了呢)
int inv[maxn];
int main(){
	a = RD();p = RD();
	inv[1] = 1;printf("1\n");
	for(int i = 2;i <= a;i++){
		inv[i] = (LL)(p - p / i) * inv[p % i] % p;
		printf("%d\n",inv[i]);
		}
	return 0;
	}
posted @ 2018-07-09 19:24  Tony_Double_Sky  阅读(179)  评论(0编辑  收藏  举报