费马小定理 求乘法逆元

//P3811 【模板】乘法逆元
#include<bits/stdc++.h>
using namespace std;
inline void write(long long X)
{
    if(X<0) {X=~(X-1); putchar(‘-‘);}
    if(X>9) write(X/10);
    putchar(X%10+‘0‘);
}
long long qpow(long long n,long long m,long long mod)
{
       long long ans=1;
    while(m)
    {
        if(m&1) ans=ans*n%mod;
        n=n*n%mod;
        m>>=1;
    }
    return ans%mod;
}
int main()
{
    long long n,p;
    scanf("%lld%lld",&n,&p);
    for(long long i=1;i<=n;i++)
        write(qpow(i,p-2,p)),printf("\n");
    return 0;
}

这一道题是洛谷P3811 【模板】乘法逆元

当然这一道题用费马小定理还是过不去的

不过可以证明这一做法的正确性

首先我们要保证题目给出的p是质数

所谓费马小定理就是

a^(p-1) ≡ 1 (mod p)

稍加化简就可以看出左边可以化为a*a^(p-2)

把那个单独的a挪到右边

所以a^(p-2)=a-1

也就是a^(p-2)就是a在模p意义下的乘法逆元

然而我们可以用快速幂来进行加速

这样一来算出一个乘法逆元的时间复杂度就是logn

但是一定要注意 必须p是负数!

上线性筛

//P3811 【模板】乘法逆元
#include<bits/stdc++.h>
using namespace std;
inline void write(long long X)
{
    if(X<0) {X=~(X-1); putchar(‘-‘);}
    if(X>9) write(X/10);
    putchar(X%10+‘0‘);
}
long long qpow(long long n,long long m,long long mod)
{
       long long ans=1;
    while(m)
    {
        if(m&1) ans=ans*n%mod;
        n=n*n%mod;
        m>>=1;
    }
    return ans%mod;
}
long long inv[3000005];
int main()
{
    long long n,p;
    scanf("%lld%lld",&n,&p);
//    for(long long i=1;i<=n;i++)
//        write(qpow(i,p-2,p)),printf("\n");
    inv[1]=1;write(1),printf("\n");
    for(int i=2;i<=n;i++)
    inv[i]=(p-p/i)*inv[p%i]%p,write(inv[i]),printf("\n");//线性筛
    return 0;
}

还有一个需要注意的地方

就是那个取模运算是很耗时间的

一开始我把代码改成线性筛之后

在输出 就是那个write的括号里又增加了一个%p

事实上是没有必要的

结果就因为这个多余的取模 y以至于我还是T一个点,,

所以千万不要多加太多%取模

原文地址:https://www.cnblogs.com/akioi/p/12207274.html

时间: 2024-08-11 03:37:50

费马小定理 求乘法逆元的相关文章

HDU - 1576(费马小定理求逆元)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9278    Accepted Submission(s): 7452 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%99

UVALive-3722 留个坑,为什么费马小定理求逆元不对??

#include <iostream> #include <cstdlib> #include <queue> #include <algorithm> #include <cmath> #include <fstream> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<

【费马小定理+快速幂+逆元】BZOJ3240-[NOI2013]矩阵游戏

[题目大意] 若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i][j]满足下面的递推式:F[1][1]=1F[i,j]=a*F[i][j-1]+b (j!=1)①F[i,1]=c*F[i-1][m]+d (i!=1)②递推式中a,b,c,d都是给定的常数.求F[n][m]. [思路] 磨了一个早上,然而UOJ上的额外数据还没有过去..BZOJ上已AC先放上来,后续慢慢磨…… *还有一点,最后输出答案的时候要先+MOD再%MOD. *MOD要勤快一点,不然会爆. 1 #include<i

51nod A 魔法部落(逆元费马小定理)

A 魔法部落 小Biu所在的部落是一个魔法部落,部落中一共有n+1个人,小Biu是魔法部落中最菜的,所以他的魔力值为1,魔法部落中n个人的魔法值都不相同,第一个人的魔法值是小Biu的3倍,第二个人的魔法值是第一个人的3倍,以此类推. 现在小Biu想知道整个部落的魔法值和是多少?由于答案比较大,请把答案对1e9+7取模之后输出. 收起 输入 输入一个数N(0 <= N <= 10^9) 输出 输出:整个部落的魔法值和模1e9+7. 数据范围 对于20%的数据,n<=100: 对于40%的数

CodeForces 300C Beautiful Numbers(乘法逆元/费马小定理+组合数公式+快速幂)

C. Beautiful Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vitaly is a very weird man. He's got two favorite digits a and b. Vitaly calls a positive integer good, if the decimal

[CodeVs1515]跳(lucas定理+费马小定理+乘法逆元)

嘿嘿嘿好久没写数学题了,偶尔看到一道写一写... 题目大意:一个(n+1)*(m+1)[0<=n, m<=10^12,n*m<=10^12]的矩阵,C(0,0)=1,C(x,y)=C(x-1,y)+C(x,y-1),求从0,0走到n,m路上最小权值(即为前面的C)和mod 10^9+7. 看到这个C(x,y)=C(x-1,y)+C(x,y-1),第一反应就是杨辉三角,所以这个矩阵其实就是一个由组合数组成的矩阵,第i行第j列的权值为C(i+j,j)[注意这个矩形起点是(0,0)]. 我们可

BZOJ_[HNOI2008]_Cards_(置换+Burnside引理+乘法逆元+费马小定理+快速幂)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1004 共n个卡片,染成r,b,g三种颜色,每种颜色的个数有规定.给出一些置换,可以由置换得到的染色方案视为等价的,求等价类计数. 分析 给出置换求等价类计数,用Burnside引理:等价类计数=(每一个置换不动点的和)/置换数.(不知道的建议去看白书) 其中不动点是指一个染色方案经过置换以后染色与之前完全相同. 1.求不动点个数. 不动点的话同一个循环内的每一个点的颜色必须相同(否则不同颜色

【日常学习】乘法逆元&amp;&amp;欧拉定理&amp;&amp;费马小定理&amp;&amp;欧拉函数应用&amp;&amp;常大学霸

转载请注明出处 [ametake版权所有]http://blog.csdn.net/ametake欢迎来看看 今天花了一个多小时终于把乘法逆元捣鼓明白了 鉴于我拙计的智商抓紧把这些记录下来 在此本栏目鸣谢里奥姑娘和热心网友himdd的帮助和支持 那么正文开始··· 逆元是干什么的呢? 因为(a/b)mod p ≠(a mod p)/(b mod p) 我们需要想一种方法避免高精 那就是把除法转化为乘法 因为(a*b) mod p = ( a mod p ) *( b mod p ) 怎么转化呢?

hdu1576-A/B-(同余定理+乘法逆元+费马小定理+快速幂)

A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10383    Accepted Submission(s): 8302 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1). Input 数据的第一行是一个