数论总结
来源:互联网 发布:风靡网络的恐怖推理图 编辑:程序博客网 时间:2024/06/06 05:24
前言:走进区域赛,切实的发现数论和思维的重要性,于是弱鸡努力总结一波!
(STL中可以用nth_element求得类似的第n大的数)
一:约数个数定理
定义g(x),为x的约数个数,对于一个数i,可分解成若干质数幂次的乘积,即:
i=prime[1]a∗prime[2]b∗…..
g(i)=(a+1)∗(b+1)∗……
二:整除的基本性质
a|b b|c => a|c
a|b a|c => a|bc
a|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|ba∗b|c and gcd(a,c)=1=>b|cgcd(ak,b)=1 {k>=1}=>gcd(a,b)=1a≡1(modb)=>gcd(a,b)=1
四:算术基本定理
任何一个大于1的自然数n,都可以唯一分解成有限个质数的乘积n=pr11∗pr22∗...∗prkkp1<p2<...<pk均为质数,r1,r2,...rk均为正整数
五:扩展欧几里得算法(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)
用途:
1)求解不定方程;
2)求解模线性方程(线性同余方程);
3)求解模的逆元;
1)求解不定方程
利用扩展欧几里得算法求解不定方程a∗x+b∗y=n的整数解的求解全过程,步骤如下:
(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∗ty=n2∗y0−a2∗t (t=0,1,2,……)调整得到正整数解
LL exgcd(LL a, LL b, LL &x, LL &y) { if(!b) { x = 1; y = 0; return a; } LL ans = exgcd(b, a%b, x, y); LL temp = x; x = y; y = temp - a / b * y; return ans; } LL cal(LL a, LL b, LL c) { LL x, y; LL gcd = exgcd(a, b, x, y); if(c % gcd != 0) return -1; x *= c / gcd; b /= gcd; if(b < 0) b =- b; LL ans = x % b; if(ans <= 0) ans += b; return ans; }
六:欧拉函数
性质
φ(n)表示n以内与n互素(包括1)的数的个数欧拉定理:若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的质因子有x,y) euler[n] = n * (1-1/x) * (1-1/y)。若有多个继续添上即可。
欧拉函数拓展:小于或等于n的数中(n > 1),与n互质的数的总和为:euler[n] * n / 2。
O(N)求解1∼n的φ(i)表:
void euler() { int i, j; eu[1] = 1;//1的欧拉函数为1 看题目而定 for(i = 2; i < MAX; i++) { if(!eu[i]) { for(j = i; j < MAX; j += i) { if(!eu[j]) eu[j] = j; eu[j] = eu[j] * (i-1) / i; } } } }
O(n√)求解φ(n):
int euler(int n) {//求n的欧拉函数 int eu = n;//欧拉函数 for(int i = 2; i*i <= n; i++) { if(n % i == 0) {//质因子 eu = eu * (i-1) / i; while(n % i == 0) n /= i;//避免再次累加 } } if(n > 1) eu = eu * (n-1) / n;//本身就是 质数 return eu; }
七:逆元(费马+快速幂 || exgcd)
费马小定理:a,p互质,则 a^(p - 1) % p = 1;
等比数列的前n项和逆元:[ (q^n - 1) / (q - 1) ] * [ (q - 1)^(mod - 1) % mod] % mod = s = (q^n - 1) * (q - 1)^(mod - 2) % mod;
八:唯一分解定理
1.有多少个约数:
先分解质因数
因数的次数分别是4,2,1
所以约数的个数为(4+1)(2+1)(1+1)=5*3*2=30个
例:
先分解质因数
720=24*32*51
因数的次数分别是4,2,1
所以约数的个数为(4+1)(2+1)(1+1)=5*3*2=30个
2.所有约数之和:
如何求一个数所有约数之和呢?
首先,应用算术基本定理,化简为素数方幂的乘积。
X = a1^k1 * a2^k2……..an^kn
X的所有素数之和可用公式(1+a1 + a1^2…a1^k1) * (1+a2 + a2^2…a2^k2) * …..(1+an + an^2…an^kn);
如:
2004 = 2^2 * 3 *167
2004所有因子之和为(1 + 2 + 2^2) * (1 + 3) * ( 1 + 167) = 4704;
程序实现的时候,可利用等比数列快速求1 + a1 + a1^2 + …..a1^n;
void init() { //素筛 memset(p,0,sizeof(p)); memset(a,0,sizeof(a)); a[0]=a[1]=1; for(int i=2;i*i<=max_n-5;i++) { if(!a[i]) { for(int j=i+i;j<=max_n-5;j+=i) a[j]=1; } } for(int i=1;i<=max_n-5;i++) { if(!a[i]) p[k++]=i; } } LL nop(LL n) { LL ans=1; for(int i=0;i<k;i++) { if(p[i]>n) break; LL res=0; while(n%p[i]==0) { res++; n/=p[i]; } ans=ans*(res+1); } if(n>1) ans*=2;//注意这一步 return ans; }
后续补充~~~
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- 数论总结
- ACM数论总结
- ACM数论总结
- 数论总结1
- 数论学习总结
- 数论学习总结2
- 数论模板总结
- 数论学习总结《一》
- Spring 框架详解(2)
- 权限管理
- POJ1745-DP初探
- 常用深度学习框架简介
- opencv3.2 安装报错解决方法
- 数论总结
- Socket编程实现服务端和客户端的交互
- 跟我一起学算法系列3---判断数组中是否含有某个整数
- 括号序列的最小代价
- flash的图像依次缩放
- XXX is not allowed to connect to this MySQL server
- 静态成员与静态函数
- [arc074e]RGB Sequence
- 学习笔记_001