数论基础知识小结
2016-11-01 10:06
183 查看
窝来大致说一下数论的一些东西:
1.欧几里得相关的两个定理:
欧几里得原理:(a,b)=(b,a mod b)
证明:
设r=a mod b,then a=kb+r
设c为a,b的任意公因数
则:c|a;c|b;c|(a−kb) <=> c|r
所以c也是b,r的因数
同理,我们设d为b,r的任意因数,则可知d也是a,b的公因数。
设A={d|a and d|b},B={d|r and d|b}, thenA=B
所以我们可以知道(a,b)=(b,r)
证明完毕!
代码如下:
扩展欧几里得算法:
贝祖等式x,y∈Z,则ax+by=(a,b)有解。
证明:
我们可以直接用扩展欧几里得算法步骤来证明:
根据(a,b)=(b,a mod b)
则设:
ax1+by1=(a,b)
bx2+(a mod b)y2=(b,a mod b)
所以:ax1+by1=bx2+(a mod b)y2
根据取模的定义,我们知道a mod b=a−⌊ab⌋⋅b
那么可以把等式右边替换:
ax1+by1=bx2+(a−⌊ab⌋⋅b)y2
我们知道,如果这样一直递归下去,那么肯定会使得y的系数为0。
这样子就能证明有解了。
那么怎么计算出方程的值呢?
我们根据递归出口:
when b==0,then x=1,y=0
理由如下:
ax+by=(a,b)=a,则x=1,y=0必然是一组解。
回到刚刚得问题上:
ax1+by1=bx2+(a−⌊ab⌋⋅b)y2
我们现在已经知道了右边等式的系数都是多少,现在怎么知道x1和y1的值呢?
移项:
a(x1−y2)+b(y1−x2+⌊ab⌋⋅y2)=0
那么显然有:
x1=y2;y1=x2−⌊ab⌋⋅y2
那么我们可以得出算法代码:
中场休息时间QAQ
中国剩余定理:
内容如下:
假如有n个同余方程:
x≡ai(mod mi),且mi两两互素。
设M=∏mi
求其在模M意义下的解。
我们假设Mi=M/mi
再设ti为Mi在模mi下的逆元,即tiMi=1(mod mi)
那么我们就可以方程的解:
x=∑aitiMi
证明:
先证明x合法。
即证明∀i∈[1,n],x≡ai(mod mi)。
x=∑j≠iajtjMj+aitiMi
则在mod mi的意义下:
x=∑0+ai=ai(mod mi)
这样x是合法的。
实际上,我们可以肯定x是小于M的。
因为如果x=∑aitimi>M合法,那么显然可以把M减去对吧。
我们这样就得到模M意义下的一个解了.
但是……
注意一下实际上我们是用CRT去求解同余方程组的。
所以我们应该没有必要那么麻烦。
我们考虑把同余方程合并:
对于x≡r1modm1
x≡r2modm2
那么我们想把它合成为1个方程。
k1m1+r1=k2m2+r2
k1m1−k2m2=r2−r1
可以扩欧来求,对吧。
当d=gcd(m1,m2)/|(r2−r1)时,无解。
我们想让这个k1尽量小,并且是正整数。
那么显然的恒等式是:
k1m1+k2m2+lcm(k1,k2)−lcm(k1,k2)=r2−r1
k1(m1%k2d)+k2(m2+p)=r2−r1
这个p显然是补足m1少了的那部分的,具体值懒得算了。
所以我们可以注意到,这个m1显然可以在模意义下去搞。
这样我们就求出了一个x,注意到,x+lcm(m1,m2)显然是通解,那么实际上我们的方程就变成了:
x=r2−r1(mod lcm(m1,m2))
这样一个一个合并就好了。
1.欧几里得相关的两个定理:
欧几里得原理:(a,b)=(b,a mod b)
证明:
设r=a mod b,then a=kb+r
设c为a,b的任意公因数
则:c|a;c|b;c|(a−kb) <=> c|r
所以c也是b,r的因数
同理,我们设d为b,r的任意因数,则可知d也是a,b的公因数。
设A={d|a and d|b},B={d|r and d|b}, thenA=B
所以我们可以知道(a,b)=(b,r)
证明完毕!
代码如下:
int gcd(int x,int y){return y ? (y,x % y) : x;}
扩展欧几里得算法:
贝祖等式x,y∈Z,则ax+by=(a,b)有解。
证明:
我们可以直接用扩展欧几里得算法步骤来证明:
根据(a,b)=(b,a mod b)
则设:
ax1+by1=(a,b)
bx2+(a mod b)y2=(b,a mod b)
所以:ax1+by1=bx2+(a mod b)y2
根据取模的定义,我们知道a mod b=a−⌊ab⌋⋅b
那么可以把等式右边替换:
ax1+by1=bx2+(a−⌊ab⌋⋅b)y2
我们知道,如果这样一直递归下去,那么肯定会使得y的系数为0。
这样子就能证明有解了。
那么怎么计算出方程的值呢?
我们根据递归出口:
when b==0,then x=1,y=0
理由如下:
ax+by=(a,b)=a,则x=1,y=0必然是一组解。
回到刚刚得问题上:
ax1+by1=bx2+(a−⌊ab⌋⋅b)y2
我们现在已经知道了右边等式的系数都是多少,现在怎么知道x1和y1的值呢?
移项:
a(x1−y2)+b(y1−x2+⌊ab⌋⋅y2)=0
那么显然有:
x1=y2;y1=x2−⌊ab⌋⋅y2
那么我们可以得出算法代码:
void exgcd(int a,int b,int &x,int &y){b ? (exgcd(b,a % b,y,x),y -= a / b * x): (x = 1,y = 0);}
中场休息时间QAQ
中国剩余定理:
内容如下:
假如有n个同余方程:
x≡ai(mod mi),且mi两两互素。
设M=∏mi
求其在模M意义下的解。
我们假设Mi=M/mi
再设ti为Mi在模mi下的逆元,即tiMi=1(mod mi)
那么我们就可以方程的解:
x=∑aitiMi
证明:
先证明x合法。
即证明∀i∈[1,n],x≡ai(mod mi)。
x=∑j≠iajtjMj+aitiMi
则在mod mi的意义下:
x=∑0+ai=ai(mod mi)
这样x是合法的。
实际上,我们可以肯定x是小于M的。
因为如果x=∑aitimi>M合法,那么显然可以把M减去对吧。
我们这样就得到模M意义下的一个解了.
但是……
注意一下实际上我们是用CRT去求解同余方程组的。
所以我们应该没有必要那么麻烦。
我们考虑把同余方程合并:
对于x≡r1modm1
x≡r2modm2
那么我们想把它合成为1个方程。
k1m1+r1=k2m2+r2
k1m1−k2m2=r2−r1
可以扩欧来求,对吧。
当d=gcd(m1,m2)/|(r2−r1)时,无解。
我们想让这个k1尽量小,并且是正整数。
那么显然的恒等式是:
k1m1+k2m2+lcm(k1,k2)−lcm(k1,k2)=r2−r1
k1(m1%k2d)+k2(m2+p)=r2−r1
这个p显然是补足m1少了的那部分的,具体值懒得算了。
所以我们可以注意到,这个m1显然可以在模意义下去搞。
这样我们就求出了一个x,注意到,x+lcm(m1,m2)显然是通解,那么实际上我们的方程就变成了:
x=r2−r1(mod lcm(m1,m2))
这样一个一个合并就好了。
#include <cstdio> #include <algorithm> #include <cstring> #define Rep(i,n) for(int i = 1;i <= n;++ i) using namespace std; typedef long long LL; LL m[1002],r[1002]; int n; LL gcd(LL a,LL b){return b ? gcd(b,a % b) : a;} void exgcd(LL a,LL b,LL &x,LL &y){b ? (exgcd(b,a % b,y,x),y -= a / b * x) : (x = 1,y = 0);} LL crt() { LL R,M,k1,k2; R = r[1],M = m[1]; for(int i = 2;i <= n;++ i) { LL dt = r[i] - R,d = gcd(m[i],M); if(dt % d)return -1; exgcd(M / d,m[i] / d,k1,k2); k1 = (k1 * dt / d) % (m[i] / d); R = R + k1 * M; M = M / d * m[i]; R %= M; } return R < 0 ? R + M : R; } int main() { while(~scanf("%d",&n)) { Rep(i,n)scanf("%lld%lld",&m[i],&r[i]); printf("%lld\n",crt()); } return 0; }
相关文章推荐
- [数论]数论的基础知识——最大公约数、最小公倍数
- C/C++基础知识:typedef用法小结
- VBA基础知识小结
- C/C++基础知识:typedef用法小结
- oracle基础知识小结
- javascript Array对象基础知识小结
- WinCE流驱动基础知识小结
- javascript之正则表达式基础知识小结
- C/C++基础知识:typedef用法详细小结
- Oracle基础知识_小结2
- squid基础知识及简单实验小结(一)
- 数据库一些基础知识汇总<键类问题小结>
- VBA基础知识小结
- javascript DOM 操作基础知识小结
- oracle基础知识小结
- javascript DOM 操作基础知识小结
- oracle基础知识小结
- oracle基础知识小结
- C/C++基础知识:typedef用法小结