新征程2.20 数论(一)同余、乘法逆元
前言:
今天开数论了,蒟蒻的我差一点就没就没听懂,由于笔者目前有太多事没干。所以这里长话短说。
首先在学习数论之前,要掌握一些前置知识,例如快速幂,gcd,lcm,模意义等知识。这是基础,不懂的自己去CSDN找资料。
同余
数论中的重要概念。给定一个正整数m,如果二整数α、b)满足m│α-b)(α-b)被m整除),就称整数α、b)对模m同余,记作α≡b)(mod m)。对模m同余是整数的一个等价关系。
显然,有如下事实
(1)若a≡0(mod m),则m|a;
(2)a≡b(mod m)等价于a与b分别用m去除,余数相同。
#include<iostream>
#include<cstdio>
using namespace std;
long long a,b,x,y,z,k;
void work(long long a,long long b)
{
if(b==0)
{
x=1;
y=0;
return;
}
work(b,a%b);
k=x;x=y;
y=k-a/b*y;
return;
}
int main()
{
scanf("%lld%lld",&a,&b);
work(a,b);
cout<<(x+b)%b;
return 0;
}
扩展欧几里得算法
扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。除了计算a、b两个整数的最大公约数,此算法还能找到整数x、y(其中一个很可能是负数)。通常谈到最大公因子时, 我们都会提到一个非常基本的事实: 给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数——这是众所周知的。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。
乘法逆元
方法一(80pts)
#include <iostream>
#define int long long
using namespace std;
int n, p, x, y, k;
int GCD(int a, int b)
{
return b ? GCD(b ,a%b) : a;
}
void work(int a, int b)
{
if (b == 0)
{
x = 1;
y = 0;
return;
}
work(b, a%b);
k = x;
x = y;
y = k - a / b * y;
return;
}
signed main()
{
scanf("%lld%lld", &n, &p);
for(int i = 1; i <= n; i ++)
{
work(i, p);
printf("%lld\n", (x%p+p)%p);
}
return 0;
}
方法二(64 pts)
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll n,p;
ll ksm(ll x,ll y)
{
if(y==0) return 1;
long long t=ksm(x,y/2)%p;
if(y%2) return (t*t*x)%p;
else return (t*t)%p;
}
int main()
{
scanf("%lld%lld",&n,&p);
for(int i=1;i<=n;i++) printf("%lld\n",ksm(i,p-2));
return 0;
}
方法三不会;
如果你在乘法逆元中仍存疑惑,那么我建议你去这里学习一下,讲的很详细
本文来自博客园,作者:deviancez,转载请注明原文链接:https://www.cnblogs.com/deviance/articles/18112961