数论总结
来源:互联网 发布:请问在淘宝怎么开店 编辑:程序博客网 时间:2024/06/05 19:50
定理/性质
约数个数定理
定义g(x),为x的约数个数
对于一个数i,可分解成若干质数幂次的乘积,即
整除的基本性质
a|b b|c => a|ca|b a|c => a|bca|b a|c => a|ib±jc (a|b,c的线性组合)a|b b|a => a=±b
a=ib±c => 公因子(a,b)=公因子(b,c)
- 证明
- 假设d为b,c的公因子,即d|b,d|c
- 则 d|ib±c=a,即d|a
- 由d|b得 d=公因子(a,b)=公因子(b,c)
- 反之,如果d是a,b的公因数,也能证出d是b,c的公因数
互素性质
a与b,c同时互素=>a与b∗c互素 p为素数且p|a∗b=>p|a or p|b a∗b|c and gcd(a,c)=1=>b|c gcd(ak,b)=1 {k>=1}=>gcd(a,b)=1 a≡1(modb)=>gcd(a,b)=1
算术基本定理
- 任何一个大于1的自然数n,都可以唯一分解成有限个质数的乘积
n=pr11∗pr22∗...∗prkk p1<p2<...<pk均为质数,r1,r2,...rk均为正整数
模运算
(a+b) mod n=(a mod n+b mod n) mod n (a∗b) mod n=(a mod n∗b mod n) mod n ab mod n=(a mod n)b mod n - 切记 除法运算 不能模运算!!!
算法
欧几里得算法(gcd)
辗转相除
function gcd(a,b:longint):longint;begin if b=0 then gcd:=a else gcd:=gcd(b,a mod b);end;
辗转相减(更相减损术/Stein算法)
- a为偶数,b为奇数 gcd(a,b)=gcd(a/2,b)
a为奇数,b为偶数 gcd(a,b)=gcd(a,b/2)
a为偶数,b为偶数 gcd(a,b)=2*gcd(a/2,b/2)
a为奇数,b为奇数 gcd(a,b)=gcd(b,a-b) {a>b}
(a或b=0 返回另一个值)或(a=b返回a或b) - 证明gcd(a,b)=gcd(b,a-b)
- a=b+(a-b)=>(a,b)=(b,a-b) {整除性质}
function gcd(a,b:longint):longint;begin if a=0 then exit(b) else if b=0 then exit(a) else if a=b then exit(a); if a mod 2=0 then if b mod 2=0 then gcd:=2*gcd(a div 2,b div 2) else gcd:=gcd(a div 2,b) else if b mod 2=0 then gcd:=gcd(a,b div 2) else if a>b then gcd:=gcd(b,a-b) else gcd:=gcd(b,b-a);end;
- 优点:
- 加法,减法和移位运算,是最基本的运算,时间消耗最小
- 乘法,除法,取余运算较慢
扩展欧几里得算法(exgcd)
求不定方程
a∗x+b∗y=1 的一组解的方法由
a∗x1+b∗y1=gcd(a,b)=gcd(b,amod b)=b∗x2+[a−⌊a/b⌋∗b]∗y2=a∗y2+b∗(x2−y2∗⌊a/b⌋) =>x1=y2 =>y1=x2−y2∗(a / b)
procedure exgcd(a,b:int64;var d,x,y:int64);var t:int64;begin if b=0 then begin d:=a; x:=1; y:=0; end else begin exgcd(b,a mod b,d,x,y); t:=x; x:=y; y:=t-y*(a div b); end;end;
- 用途:
- 1)求解不定方程;
- 2)求解模线性方程(线性同余方程);
- 3)求解模的逆元;
1)求解不定方程
利用扩展欧几里得算法求解不定方程
(1)先计算
Gcd(a,b) ,若n不能被Gcd(a,b) 整除,则方程无整数解;否则,在方程两边同时除以Gcd(a,b) ,得到新的不定方程a2∗x+b2∗y=n2 此时Gcd(a2,b2)=1; (2)利用扩展欧几里德算法求出方程
a2∗x+b2∗y=1 的一组整数解x0,y0 ,则n2∗x0,n2∗y0是方程a2∗x+b2∗y=n2的一组整数解; (3)根据数论中的相关定理,可得方程
a2∗x+b2∗y=n2 的所有整数解为:x=n2∗x0+b2∗t y=n2∗y0−a2∗t (t=0,1,2,……)
调整得到正整数解
最小公倍数(lcm)
lcm(a,b)=a∗b/gcd(a,b)
快速幂
- 其实就是倍增的思想
a1,a2,a4...a2n依次求出来 - 所以快速+幂/乘/加 都可以
ab mod n
- b and 1 取出二进制下最后一位
- b shr
ab=a2n⋅......⋅a16⋅a8⋅a4⋅a2 - 每次求出
a2i,若二进制下该位为1,即有这位对结果的贡献,乘a2i
function f(a,b,n:int64):int64; //(a^b) mod nvar t,y:int64;begin t:=1; y:=a; while b<>0do begin if(b and 1)=1 then t:=t*y mod n; y:=y*y mod n; b:=b shr 1; end; exit(t);end;
[acbd]n
矩阵乘法求斐波那契数列
var x:array[0..100000000]of longint; i,j,k,n:longint; t,y:array[1..2,1..2]of int64;function g(f:longint):longint;var a,b,c,d:longint;begin t[1,1]:=1; t[1,2]:=0; t[2,1]:=0; t[2,2]:=1; y[1,1]:=0; y[1,2]:=1; y[2,1]:=1; y[2,2]:=1; k:=1000000007; while f<>0 do begin if (f and 1)=1 then begin a:=(t[1,1]*y[1,1]+t[1,2]*y[2,1])mod k; b:=(t[1,1]*y[1,2]+t[1,2]*y[2,2])mod k; c:=(t[2,1]*y[1,1]+t[2,2]*y[2,1])mod k; d:=(t[2,1]*y[1,2]+t[2,2]*y[2,2])mod k; t[1,1]:=a mod k; t[1,2]:=b mod k; t[2,1]:=c mod k; t[2,2]:=d mod k; end; a:=(y[1,1]*y[1,1]+y[1,2]*y[2,1])mod k; b:=(y[1,1]*y[1,2]+y[1,2]*y[2,2])mod k; c:=(y[2,1]*y[1,1]+y[2,2]*y[2,1])mod k; d:=(y[2,1]*y[1,2]+y[2,2]*y[2,2])mod k; y[1,1]:=a mod k; y[1,2]:=b mod k; y[2,1]:=c mod k; y[2,2]:=d mod k; f:=f shr 1; end; exit((x[1]*t[2,1]+x[0]*t[2,2])mod k);end;begin readln(n); k:=1000000007; x[0]:=1; x[1]:=1; writeln(g(n-1)); for i:=2 to n do x[i]:=(x[i-1]+x[i-2])mod k; writeln(x[n]);end.
矩阵乘法优化递推式
例如
线性筛
var prime:array[0..3562115]of longint; check:array[0..60000000]of boolean; i,j:longint; n,len:longint;begin readln(n); for i:=2 to n do begin if check[i]=false then begin inc(len); prime[len]:=i; end; for j:=1 to len do begin if i*prime[j]>n then break; check[i*prime[j]]:=true; if i mod prime[j]=0 then break; end; end; writeln(len); for i:=1 to len do write(prime[i]);end.
判断素数
O(N−−√)
我们知道对于一个的他的因子的大小不超过
O(log2n)
费马小定理:当p为素数时 ap≡a(modp)即ap−1≡1(modp) 我们枚举几个a判断是否成立即可,要求选取的2<a<p,ap(modp)用快速幂处理 欧拉定理:若a与n互质,那么有aφ(n)≡1(mod n)用于求乘法逆元 若p是一个质数,那么φ(p)=p−1,注意φ(1)=1。 - 积性函数
若m与n互质,那么φ(n∗m)=φ(n)∗φ(m) n=pk且p为质数,那么φ(n)=pk−p(k−1)=p(k−1)∗(p−1)
当n为奇数时有φ(2∗n)=φ(n) ∑d|n φ(d)=n φ(n)=n∏p为素数且p|np−1p
O(N)求解1∼n的φ(i)表
const maxn=1000000;var check:array[0..maxn]of boolean; phi,prime:array[0..maxn]of longint; n,i,j,ans,len:longint;begin readln(n); len:=0; for i:=2 to n do begin if check[i]=false then begin inc(len); phi[i]:=i-1; prime[len]:=i; end; for j:=1 to len do begin if prime[j]*i>n then break; check[i*prime[j]]:=true; if i mod prime[j]=0 then begin phi[i*prime[j]]:=phi[i]*prime[j]; break; end else phi[i*prime[j]]:=phi[i]*(prime[j]-1); end; end; for i:=1 to n do writeln(phi[i]);end.
O(n−−√)求解φ(n)
const maxn=1006350;var check:array[0..maxn]of boolean; prime:array[0..maxn]of longint; i,j:longint; n,s,ans,len,t:longint;begin readln(n); s:=n; ans:=n; n:=trunc(sqrt(n)); len:=0; for i:=2 to n do begin if check[i]=false then begin inc(len); prime[len]:=i; end; for j:=1 to len do begin if prime[j]*i>n then break; check[prime[j]*i]:=true; if i mod prime[j]=0 then break; end; end; for i:=1 to len do begin if s mod prime[i]=0 then begin ans:=(ans div prime[i])*(prime[i]-1); while s mod prime[i]=0 do s:=s div prime[i]; end; end; if s<>1 then ans:=(ans div s)*(s-1); //1700016764 writeln(ans);end.
莫比乌斯函数
性质
对于任意正整数n有 :∑d|nμ(d)={10d=1d>1 对于任意正整数n有: ∑d|nμ(d)d=φ(n)n
O(N)求解1∼n的μ(i)表
const maxn=100000;var check:array[0..maxn]of boolean; mu,prime:array[0..maxn]of longint; i,j,len,n:longint;begin readln(n); mu[1]:=1; len:=0; for i:=2 to n do begin if check[i]=false then begin mu[i]:=-1; inc(len); prime[len]:=i; end; for j:=1 to len do begin if i*prime[j]>n then break; check[i*prime[j]]:=true; if i mod prime[j]=0 then begin mu[i*prime[j]]:=0; break; end else mu[i*prime[j]]:=-mu[i]; end; end; for i:=1 to n do writeln(i,' ',mu[i]);end.
求解模方程组
中国剩余定理可以求解模数互质的情况,但根据ydc的课件,我们用其他方式合并
扩展欧几里得求出
令
然后我们合并为
求逆元
求逆元的方法汇总
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- ACM数论总结
- ACM数论总结
- 数论总结1
- 数论学习总结
- 数论学习总结2
- 数论模板总结
- 数论学习总结《一》
- Android SDK 国内镜像配置
- IOS 百度地图定位,显示地理位置
- C语言运算中的数据类型自动转换原则
- 拒绝忽悠 移动GPU全解读
- 【hadoop0001】hadoop环境搭建
- 数论总结
- Docker的网络工作原理
- ios中uitableview显示两列或多列数据
- ZOJ2833---Friendship
- undefined reference to 'pthread_create'问题解决【转载】
- 婚姻和家庭的作用
- 职业解答
- Modelsim 一个错误记录: # ** Error: (vsim-3601) Iteration limit reached at time 29605 ns.
- python print 重定向+追加到文件