zoukankan      html  css  js  c++  java
  • 乘法逆元 学习笔记

    下面设要求逆元的数是 n ,对 mo 求逆元。

    费马小定理

    当模数为质数才能用。 逆元为:(n^{(mo-2)}\%mo)快速幂可以解决。Time: (O(log\,mo))一般(mo=1000000007)(998244353)时,(log\,mo)大约是30。

    Ex_gcd

    模数不为质数也可以用。 求解 exgcd(n,mo,x,y),得到的x就是逆元。Time和费马小定理一样。

    注意求解完建议 x=(x+mo)\%mo 。怕x是负数或者大于mo。(但是似乎x不会小于 -mo ,我也不清楚,保险可以加个while什么的)


    线性求逆元

    递推公式如下:

    inv[i]=mo-(mo/i)*inv[mo%i]%mo;

    Time:(O(n))

    坏处:时间慢,n过大时数组存不下

    好处:可以求出1~n所有逆元,所以建议求多次逆元时使用

    不过好像如果数组存不下,可以用递归+记忆化(比如你数组能开十万,你就把十万内的逆元记下来,其它的就递归硬算)跑起来挺快的

    #include<bits/stdc++.h>
    using namespace std;
    int mo=998244353;
    int n,inv[10000007];
    
    int do_inv(int z){
    	if(z<=10000000){//数组能开多大就开多大
    		if(inv[z]!=-1)return inv[z];
    		inv[z]=mo-(mo/z)*do_inv(mo%z)%mo;
    		return inv[z];
    	}
    	else return mo-(mo/z)*do_inv(mo%z)%mo;
    }
    
    int main(){
        memset(inv,-1,sizeof inv);
        inv[1]=1;
        while(cin>>n)cout<<do_inv(n)<<endl;
    }
    
  • 相关阅读:
    Leecode no.22 括号生成
    修改mysql数据库的时区
    Django 路由层之反向解析
    学习 Django 的几个教程网址
    leetcode周赛 242
    AcWing第二次热身赛
    AcWing夏季每日一题--最长公共子序列
    AcWIng夏季每日一题--序列最大收益
    leetcode周赛 241
    第十二届蓝桥杯C++ B组
  • 原文地址:https://www.cnblogs.com/BlankAo/p/14018200.html
Copyright © 2011-2022 走看看