知识点:乘法逆元,逆元的求法,二元一次方程求通解,a的n次方求余数
一,乘法逆元
乘法逆元的概念类似于倒数(
ax=1,a−1=x
),不过是在取余数的情况下的倒数。
如果
(a×x)%p=1
,则称x是a模p的逆元。另一种记法:
ax=1( mod p)
,即等式两边去膜
p
运算。显然
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5685
逆元的作用:已知
F%p和a%p
的值,求
(Fa)%p
(我们不知道
F和a
的值,且
F%a=0
)。
a
模
模
p
运算中,乘以
逆元的存在性质:当 a与p 互素的时候,逆元才存在解,如果不互素则无解(这里说的都是整数解)。显然如果p是素数(质数),那么 1 到
二,求逆元
下面该学习如何求解乘法逆元
暴力破解:
档模
p
比较小的时候,我们可以枚举
扩展欧几里得算法:
首先要了解欧几里得算法,也就是辗转相除法,
上述过程求解ax+py=gcd(a,p)的过程,并不要求gcd(a,p)一定等于1。由上述过程 ,我们可以推广得到求解任意二元一次方程ax+by=c的解。
需要注意的一点是只有当 c%gcd(a,b)=0 时,方程 ax+by=c 才有整数解证明如下:
扩展欧几里得算法代码如下:
int exgcd(int a, int b, int &x, int &y)
{
if(b==0){
x = 1;
y = 0;
return a;
}else{
int _gcd = exgcd(b,b%a,x,y);
int tmp = x - (a/b)*y;
x = y;
y = tmp;
return _gcd;
}
}
x = (x % p + p) % p; // 通常需要求解最小的正整数逆元解ax=1(mod p)
// 再次提醒a和p互素,即gcd(a,p) = 1
费马小定理:
费马小定理:假如p是质数,且 gcd(a,p)=1 ,那么 ap−1≡1 ( mod p) ,即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
由
ap−1=1 ( mod p)
很容易得到
a∗ap−2=1 ( mod p)
,那也就是
a
的逆元是
需要注意的是需要判断 a和p 是否互素,如果用gcd来判断的话,那还不如直接用扩展欧几里得算法。
O(n)求1~n逆元表:
由前面可知,当
p
为素数时,
采用递推的方法来求解所有
也注意上面求出来的逆元是负数,很多时候需要转化为正整数,而且是最小的正整数逆元。
代码如下:
const int p = 13;
int inv[p+2];
inv[1] = 1;
for (int i = 2;i < p;i++)
inv[i] = ((p - p / i)*inv[p%i]) % p;
对于1到p的都只存在一个小于p的逆元,为什么?
三,a的n次方取余
如求
20172017%1777
或者
2100%9973
的值:
代码如下:
long long remainder_of_an_exponential_recur(int a, int b, int c)
{ // 递归求 (a^b)%c
if (b == 0)
return 1;
long long tmp = remainder_of_an_exponential_recur(a, b >> 1, c);
if (b & 1)
return (tmp*tmp*a) % c;
else
return (tmp*tmp) % c;
}
long long remainder_of_an_exponential_loop(int a, int b, int c)
{ // 递推求 (a^b)%c
long long res = 1;
long long tmp = a;
while (b)
{
if (b & 1) res = (res*tmp) % c;
tmp = (tmp*tmp) % c;
b >>= 1;
}
return res;
}
如果除数是
2i
,求余数。这个比较简单
a%2
也就是求
a
的二进制表示方式中的最后一位的值。
最后一个需要说的是公式:
ab%p=a%(b×p)b%p。(其中a%b=0)
。这个公式一般都是在无法计算得到
a
的情况下使用的,这个公式当然也可以两边乘以
在ALL X问题中:http://acm.hdu.edu.cn/showproblem.php?pid=5690。
要求检验一个全由
x
组成的
既可以利用余数有限重复循环的方法,即按照除法的方法依次计算余数,如果余数重复,那么就开始进入了循环,而余数的个数是有限的,小于k个。这和求 a/b 的小数表示形式是一样的(它是无限的添加0,本题中是无限的添加x)。
另一种方法是求解 F(x,m) ,容易知道 F(x,m)=x×10m−19 ,那么 F(x,m) mod k=[(x%k)×10m−19%k]%k ,相当于求解 10m−19%k ,利用上述公式可以得到 10m−19%k=(10m−1)%(9k)9%k=[10m%(9k)]−19%k 。而 [10m%(9k)] 可以利用a的n次方取余的方法来求解。
求
an
,可以用快速幂乘,a可以是矩阵。
an=an/2∗an/2,n是偶数
a^{n}=a^{n/2}*a^{n/2}*ahttps://www.baidu.com/s?ie=UTF-8&wd=快速幂乘&tn=98012088_4_dg&ch=10
,n是奇数数
参考:
http://blog.csdn.NET/tsaid/article/details/7365936
http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html
https://wenku.baidu.com/view/c1b06ea60029bd64783e2c63.html
http://blog.csdn.net/stcyclone/article/details/52081822