• 【笔记】逆元简单操作


    数论--逆元

    2020.1.20 li'ao老师
    

    功能引入

    加、减、乘都可以随时取模,那除以呢?

    我们让模意义下除以一个数等于乘他的逆元

    定义

    如果xy≡1(mod n),则在模n意义下,y为x的逆元,记为x^-1
    
    (逆元可能有多个)
    

    逆元的存在性

    x在模n意义有逆元当且仅当(x,n)=1
    

    证:

    xy ≡ 1(mod n)
        
    存在k使xy=kn+1
    
    =>xy-kn=1
    
    满足形式ax+by=kgcd(x,y)
    
    此时gcd(x,n)=1
    

    寻找逆元

    1.exgcd

    xy ≡ 1(mod n)
    
    xy=kn+1
    
    xy-kn=1
    
    满足形式ax+by=kgcd(x,y)
    
    故可以通过exgcd找逆元
    

    2.线性求逆元

    逆元的其他求法:线性求逆元
    
    设n是一个质数,那么1到n-1都与n互质,因此1到n-1在模n意义下都有逆元
    
    1的逆元为1
    
    对x(1<x<n)求逆元
    
    设a=⌊n/x⌋,b=n%x
    
    n=a*x+b
    
    b=-a*x(在模n意义下)
    
    inv[b]*b=-int[b]*a*x
    
    1≡-inv[b]*a*x(mod n)
    
    -inv[b]*a即为x的逆元
    
    x的逆元可以用比他小的数的逆元得到
    
    递推可以求得1到n-1在模n意义下的逆元
    
    
    int a = n / x;
    
    int b = n % x;
    

    [inv[x]=-a*inv[b] ]

    求1~n在模p意义下的逆元

    
    int inv[N] , n , p;
    
    cin >> n >> p;
    
    inv[1]=1;
    
    for (int i = 2 ; i <= n ; i++)
    
    {
    
        int a = p / i;
        
        int b = p % i;
        
        inv[i] = (p - inv[b]*a) % p;
    }
    
    

    版子题

    【P3811 【模板】乘法逆元】

    AC代码

    
    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 3000010
    #define M 100010
    
    using namespace std;
    
    long long inv[N],n,p;//注意开longlong 
    
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    int main()
    {
        cin>>n>>p;
    	
    	inv[1]=1;
    	for(int i=2;i<=n;i++)
    	{
    		int a=p/i;
    		int b=p%i;
    		inv[i]=(p-a)*inv[b]%p;		//随时取模注意正化
    		//inv[i]=(p - a*inv[b] )%p 会负 
    		
    
    //		if(inv[i] < 0)
    //		{
    //			cout << i << ' ' << inv[i] << endl;
    //			break; 
    //		}
    		
    		//若i是p的因数,则b==0
    		//若i与n不互质,b为p的因数 ??
    	}
    	for(int i=1;i<=n;i++)	
    		printf("%d
    ",inv[i]);	
    		//cout TLE
    	return 0;
    }
    
    

    逆元求组合数

  • 相关阅读:
    HTTP Continuation or nonHTTP traffic 数据包
    linuxTcp IP协议栈源码阅读笔记(转)
    使用Windows命令行启动服务
    数据库集群
    ShellExecute
    oracle 中数据库完全导入导出:cmd命令行模式
    理解ORACLE数据库字符集
    asp.net 编码设置
    ShellExecute与ShellExecuteEx的用法
    C++用位运算实现循环移位
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/12219124.html
Copyright © 2020-2023  润新知